爲了讓用戶體驗更好,頁面前端往往是通過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