Asp.net Mvc提供了DependencyResolver、Routing、Filter、 Modelbinder等webForm所沒有新概念,提升Web服務編寫的便利性,記得好久以前寫的ashx處理程序,因爲沒有Routing和Modelbinder,代碼裏寫了不少switch case,還有不少參數類型轉換,寫得滿頭大汗。如今,開發WebSocket服務端時,一樣遇到和ashx差很少的情況:解析數據包,分析Command值,switch(command),而後一個case一個case分支的服務邏輯實現。html
若是咱們在webSocket協議之上提出一種請求和回覆的數據包的格式約定,正如http在tcp之上的協議約定同樣,那麼就能夠仿照Asp.net Mvc同樣,實現服務端的DependencyResolver、Controller、Filter等相似功能,將來業務功能的開發只要繼承Controller便可,輕鬆地實現業務功能代碼和基礎通信代碼徹底分開。固然這個格式約定能夠做很簡單化,而不是直接複製Http協議,咱們如今約定的格式能夠以下:git
{"api":"Login","id":2,"body":["name","password"]}
客戶端請求如上的數據到服務器,服務器就自行調用它裏面的Login方法,而後將返回值放到請求json的body字段返回給客戶端:github
public bool Login(string theName, string thePassword) { return theName == "name" && thePassword == "password"; }
上面的Login方法是一個具體的業務Api,其所在的class派生於FastApiService,FastApiService的職責是反射調用其Login成員方法。web
關於反射性能,能夠對Login方法先生成一個調用的委託,緩存起來供下次調用,能夠參考asp.net Mvc的ActionMethodDispatcher:http://www.projky.com/asp.netmvc/4.0/System/Web/Mvc/ActionMethodDispatcher.cs.htmljson
FastApiService的職責接口以下:c#
/// <summary> /// 定義Api服務的執行 /// </summary> public interface IFastApiService : IDisposable { /// <summary> /// 執行Api行爲 /// </summary> /// <param name="actionContext">Api行爲上下文</param> void Execute(ActionContext actionContext); }
這裏咱們偷工減料了,不做那麼強大,分析請求數據包的api鍵的字符串值,查找哪一個FastApiService定義了相關的成員方法,從而New出這個FastApiService實例,再調用Execute(ActionContext actionContext);api
Asp.netMvc+Autofac管理EF的Context對象很是方便,這得利於Asp.netMvc提供了DependencyResolver,能夠把Controller的建立給IOC組件來管理,DependencyResolver接口很簡單,傳入對象類型,返回對象實例,中間過程由IOC來處理。數組
查找哪一個FastApiService定義了相關的成員方法,從而New出這個FastApiService實例緩存
這裏獲取FastApiService的實例,改成DependencyResolver來獲取服務器
Filter實際是附屬的一種東西,在FastApiService的Execute前和後各執行各類Filter就能夠了,不論是全局的Filter,仍是打特性的,終究都是Filter,約定好他們的執行順序就OK!有了Filter,媽媽不再擔憂別人還未登陸就請求個人其它Api服務了。
/// <summary> /// Cpu性能檢測控制服務 /// </summary> public class CpuCounterService : FastApiService { /// <summary> /// 獲取版本號 /// </summary> /// <returns></returns> [Api] [LogFilter("獲取版本號")] public string GetVersion() { return this.GetType().Assembly.GetName().Version.ToString(); } /// <summary> /// 訂閱/取消Cpu變化通知 /// </summary> /// <returns></returns> [Api] [LogFilter("訂閱/取消Cpu變化通知")] public bool SubscribeCpuChangeNotify(bool subscribe) { this.CurrentContext.Session.TagData.Set("NotifyFlag", subscribe); return true; } }
document.title = '正在鏈接到服務器 ..'; var ws = new fastWebSocket('ws://localhost:8282/'); // 註冊api ws.bindApi("CpuTimeChanged", function (data) { lineChart.addData(data); }); ws.onclose = function (e) { document.title = '鏈接已斷開:' + e.code + '' + e.reason; }; ws.onopen = function (e) { ws.invkeApi('getVersion', [], function (version) { document.title = '服務器版本號:' + version; }, function (ex) { alert('異常:' + ex); }); };