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); }); };