實現無縫兼容ajax/websocket網頁應用和服務 原

爲了讓用戶體驗更好,頁面前端往往是通過ajax來進行數據處理;由於瀏覽器的設計原因每個域名下的連接有限,這樣導致了同時進行ajax數據請求效率無法得到有效地提升,爲了提高效率和傳統HTTP協議上的限制,因此websocket的應運而生。由於websocket是後期提供的升級協議,所以現有很多WEB服務邏輯無法同時兼容兩種協議處理;導致了頁面前端就無法更有效地利用websocket優勢,更多的是在這兩者間做一種選擇。

FastHttpApi

爲了更好地利用websocket的優勢和傳統性兼容,FastHttpApi實現無縫兼容Ajax和Websocket數據請求,開發者只需要寫一分服務端代碼!更重要的是FastHttpApi可以讓開發者完全不用寫Javascript調用的API腳本!在新版本的FastHttpApi中實現了一個自定義工具,只要設置好這個自定義工具開發者在VS編寫邏輯控制器的情況下就自動生成對應調用的API腳本文件。插件安裝說明

腳本調用機制

當編寫完成邏輯控制器後,就可以把對應的腳本引用到網頁上(生成腳本還支持await調用),直接調用相關方法即可。

var result = await $ListEmployees();
        var empsBlock = new Vue({
            el: '#lstbody',
            data: result
        });

組件腳本默認是隱藏了調用方式,使用者並不用去關心其中細節(具本可以看FastHttpApi代碼瞭解);當組件探測到有可用的websocket連接的時候就會自動使用websocket進行數據請求,這樣對於有多個數據塊同時加載的時候比傳統的ajax有着更高效的通訊優勢。如果websocket不可用或還沒初始化完成時,那組件就會自動使用傳統的ajax模式進行處理。

示例實現

爲了更好地體現FastHttpApi在這方面的功能,以下針對Northwind的訂單業務進行一個分頁查詢。

控制器代碼

複製代碼

/// <summary>
        /// 訂單查詢
        /// </summary>
        /// <param name="employeeid">僱員ID</param>
        /// <param name="customerid">客戶ID</param>
        /// <param name="index">分頁索引</param>
        /// <returns>{Index:0,Pages:0,Items:[order],Count:0}</returns>
        public object ListOrders(int employeeid, string customerid, int index, IHttpContext context)
        {
            Func<Order, bool> exp = o => (employeeid == 0 || o.EmployeeID == employeeid)
             && (string.IsNullOrEmpty(customerid) || o.CustomerID == customerid);
            int count = mOrders.Count(exp);
            int size = 20;
            int pages = count / size;
            if (count % size > 0)
                pages++;
            var items = mOrders.Where(exp).Skip(index * size).Take(size);
            return new { Index = index, Pages = pages, Items = items, Count = count };
        }

複製代碼

以上是針對一個訂單分析查詢的邏輯方法,在編寫完成邏輯控制器後在相應代碼文件屬性->自定義工具輸入'JASPI'即可生成對應的javascript腳本:

複製代碼

var $ListOrders$url='/listorders';
///<summary>
/// 訂單查詢
/// </summary>
/// <param name="employeeid">僱員ID</param>
/// <param name="customerid">客戶ID</param>
/// <param name="index">分頁索引</param>
/// <returns>{Index:0,Pages:0,Items:[order],Count:0}</returns>
function $ListOrders(employeeid,customerid,index,useHttp)
{
    return api($ListOrders$url,{employeeid:employeeid,customerid:customerid,index:index},useHttp).sync();
}
function $ListOrders$async(employeeid,customerid,index,useHttp)
{
    return api($ListOrders$url,{employeeid:employeeid,customerid:customerid,index:index},useHttp);
}

複製代碼

以上代碼都是插件自動生成,如果控制器方法有註釋同樣也會生成到JS中,開發完全只需要把腳本文件引用到頁面即可。插件針對控制生成了兩個方法,一個同步一個異步;同步方法是支持await調用,異步方法則在調用過程中指定Callback函數;其中useHttp參數是強行指定使用ajax請求。

頁面集成

FastHttpApi是不支持服務端視圖引擎,所以只能使用前端框架來整合頁面,在這裏選擇了VueJS(這個框架的確不錯,功能豐富入門簡單即看即用)。在VueJS的支撐下頁面代碼就變得比較簡單

複製代碼

<form class="form-inline">
                            <div class="form-group">
                                <label for="exampleInputName2">Employee:</label>
                                <select id="lstEmployees" style="margin:5px;">
                                    <option value=""></option>
                                    <option v-for="item in Data" v-bind:value="item.ID">{{item.Name}}</option>
                                </select>
                            </div>
                            <div class="form-group">
                                <label for="exampleInputEmail2">Customer:</label>
                                <select id="lstCustomers" style="margin:5px;">
                                    <option value=""></option>
                                    <option v-for="item in Data" v-bind:value="item.ID">{{item.Name}}</option>
                                </select>
                            </div>
                            <br />
                            <button type="button" onclick="searchOrder(0)" class="btn btn-default">Search</button>
                        </form>
                        <table class="table">
                            <thead>
                                <tr>
                                    <th>#</th>
                                    <th>OrderID</th>
                                    <th>ShipName</th>
                                    <th>ShipAddress</th>
                                    <th>City</th>
                                    <th>OrderDate</th>
                                </tr>
                            </thead>
                            <tbody id="lstbody">
                                <tr v-for="item in Data.Items">
                                    <td></td>
                                    <td>{{item.OrderID}}</td>
                                    <td>{{item.ShipName}}</td>
                                    <td>{{item.ShipAddress}}</td>
                                    <td>{{item.City}}</td>
                                    <td>{{item.OrderDate}}</td>
                                </tr>
                            </tbody>
                        </table>
  <nav aria-label="Page navigation">
                            <ul id="pagination" class="pagination">

                            </ul>
                        </nav>

複製代碼

頁面功能整合了僱傭員、客戶兩個下選擇條件,訂單信息顯示和分頁。接下來整全的javascrip腳就更簡單了:

複製代碼

var app6;
    $(document).ready(function () {
        app6 = new Vue({
            el: '#lstbody',
            data: { Data: [] }
        });
        init();
    });

    async function init() {
        var result = await $GetEmployeesName();
        var app4 = new Vue({
            el: '#lstEmployees',
            data: result
        });

        result = await $GetCustomersName();
        var app5 = new Vue({
            el: '#lstCustomers',
            data: result
        });
        searchOrder(0);
    }

    async function searchOrder(index) {
        var result = await $ListOrders($('#lstEmployees').val(), $('#lstCustomers').val(), index);
        app6.Data = result.Data;
        pagination(index, result.Data.Pages);
    }

複製代碼

實際處理效果

這個頁面一開始就分別加載3項數據,如果按傳統的ajax加載來看一般都串行加載,後前等前才完成後才能請求加載。當在FastHttpApi的支撐下結果又怎樣呢,我們看一下整個頁面的加載情況: 

從圖上我們可以看到,由於websocket沒有初始化完成,所以獲取僱員的數據是直接ajax了,後面的客戶和默認訂單查詢走了websocket通訊。如果頁面有大量數據塊整合的情況,那使用FastHttpApi會有很大的加載效率優勢。

瞭解更多FastHttpApi

項目地址:https://github.com/IKende/FastHttpApi

完全基於FastHttpApi實現的官方網站:http://www.ikende.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章