问题场景

Asp.net Mvc提供了DependencyResolver、Routing、Filter、 Modelbinder等webForm所没有新概念,提高Web服务编写的便利性,记得很久之前写的ashx处理程序,由于没有Routing和Modelbinder,代码里写了很多switch case,还有很多参数类型转换,写得满头大汗。现在,开发WebSocket服务端时,同样遇到和ashx差不多的状况:解析数据包,分析Command值,switch(command),然后一个case一个case分支的服务逻辑实现。

优化思路

如果我们在webSocket协议之上提出一种请求和回复的数据包的格式约定,正如http在tcp之上的协议约定一样,那么就可以仿照Asp.net Mvc一样,实现服务端的DependencyResolver、Controller、Filter等类似功能,未来业务功能的开发只要继承Controller即可,轻松地实现业务功能代码和基础通讯代码完全分开。当然这个格式约定可以作很简单化,而不是直接复制Http协议,我们现在约定的格式可以如下:

{"api":"Login","id":2,"body":["name","password"]}
  • 请求和回复的内容都为Json文本;
  • api指明请求到远程端的哪个api方法;
  • id为本数据包的唯一标识符;
  • body为请求的远程端api的参数值,为数组;如果是回复,则为回复的对象的json文本

客户端请求如上的数据到服务器,服务器就自行调用它里面的Login方法,然后将返回值放到请求json的body字段返回给客户端:

public bool Login(string theName, string thePassword)
{
return theName == "name" && thePassword == "password";
}

设计之道

Api服务基础类(FastApiService)的设计

上面的Login方法是一个具体的业务Api,其所在的class派生于FastApiService,FastApiService的职责是反射调用其Login成员方法。

关于反射性能,可以对Login方法先生成一个调用的委托,缓存起来供下次调用,可以参考asp.net Mvc的ActionMethodDispatcher:http://www.projky.com/asp.netmvc/4.0/System/Web/Mvc/ActionMethodDispatcher.cs.html

FastApiService的职责接口如下:

/// <summary>
/// 定义Api服务的执行
/// </summary>
public interface IFastApiService : IDisposable
{
/// <summary>
/// 执行Api行为
/// </summary>
/// <param name="actionContext">Api行为上下文</param>
void Execute(ActionContext actionContext);
}

Routing的设计

这里我们偷工减料了,不作那么强大,分析请求数据包的api键的字符串值,查找哪个FastApiService定义了相关的成员方法,从而New出这个FastApiService实例,再调用Execute(ActionContext actionContext);

DependencyResolver的设计

Asp.netMvc+Autofac管理EF的Context对象非常方便,这得利于Asp.netMvc提供了DependencyResolver,可以把Controller的创建给IOC组件来管理,DependencyResolver接口很简单,传入对象类型,返回对象实例,中间过程由IOC来处理。

查找哪个FastApiService定义了相关的成员方法,从而New出这个FastApiService实例

这里获取FastApiService的实例,改为DependencyResolver来获取

各部件执行流程

Filter哪里去了

Filter实际是附属的一种东西,在FastApiService的Execute前和后各执行各种Filter就可以了,不管是全局的Filter,还是打特性的,终究都是Filter,约定好他们的执行顺序就OK!有了Filter,妈妈再也不担心别人还未登录就请求我的其它Api服务了。

成果展示

服务器c#代码片断

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

客户端js代码片断

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

栗子下载

https://github.com/xljiulang/NetworkSocket

一种仿照Asp.net Mvc思维构建WebSocket服务器的方法的更多相关文章

  1. ASP.NET MVC 5 - 查询Details和Delete方法

    在这部分教程中,接下来我们将讨论自动生成的Details和Delete方法. 查询Details和Delete方法 打开Movie控制器并查看Details方法. public ActionResul ...

  2. [转]ASP.NET MVC 5 - 查询Details和Delete方法

    在这部分教程中,接下来我们将讨论自动生成的Details和Delete方法. 查询Details和Delete方法 打开Movie控制器并查看Details方法. public ActionResul ...

  3. asp.net MVC webservice 报次错解决方法

    asp.net  MVC  webservice  报次错解决方法: 解决方法: 在 RouteConfig.cs public static void RegisterRoutes(RouteCol ...

  4. T4 模板 : 一种提升ASP.NET MVC开发速度方法

    最近由于需要在框架中提供一些自定义模板的功能,找到了一篇博客,可惜似乎是翻译工具直接翻的,读不通顺,就试着自己翻译下,我不会完全翻译原文的句子,可能会对原文进行小范围的我认为更合适的句子并添加些注释, ...

  5. 测试驱动 ASP.NET MVC 和构建可测试 ASP.NET MVC 应用程序

    [测试驱动 ASP.NET MVC] http://t.cn/8kdi4Wl [构建可测试 ASP.NET MVC 应用程序]http://t.cn/8kdi4Wj

  6. ASP.NET MVC 实现AJAX跨域请求方法《1》

    ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...

  7. Asp.net MVC 中超链接的三个方法及比较

    在Asp.net WebForm开发中,我们通过a标签进行跳转时,通常的写法是:<a href="index.aspx">首页</a>, 在Asp.net ...

  8. asp.net mvc webapi 实用的接口加密方法

    在很多项目中,因为webapi是对外开放的,这个时候,我们就要得考虑接口交换数据的安全性. 安全机制也比较多,如andriod与webapi 交换数据的时候,可以走双向证书方法,但是开发成本比较大, ...

  9. asp.net mvc webapi 实用的接口加密方法(转载)

    在很多项目中,因为webapi是对外开放的,这个时候,我们就要得考虑接口交换数据的安全性. 安全机制也比较多,如andriod与webapi 交换数据的时候,可以走双向证书方法,但是开发成本比较大, ...

随机推荐

  1. easyui-validatebox 验证两次密码是否输入一致

    验证两次密码是否输入一致 $.extend($.fn.validatebox.defaults.rules, {        /*必须和某个字段相等*/        equalTo: { vali ...

  2. NetBIOS

    NetBIOS是Network Basic Input/Output System的缩写,严格来说它不是一个网络协议,而是一套API,为局域网内应用程序通信提供会话层(OSI七层参考模型)的支持. N ...

  3. 怎样在python中获取时间?

    from time import strftime date = strftime('%y%m%d') hour = strftime('%H%M%S')

  4. Python中的逗号有什么作用?

    最近研究python  遇到个逗号的问题 一直没弄明白 今天总算搞清楚了 1.逗号在参数传递中的使用: 这种情况不多说  没有什么不解的地方 就是形参或者实参传递的时候参数之间的逗号 例如def  a ...

  5. Java虚拟机详解01----初识JVM

    主要内容如下: JVM的概念 JVM发展历史 JVM种类 Java语言规范 JVM规范 一.JVM的概念: JVM: Java Virtual Machine,意为Java虚拟机. 虚拟机: 指通过软 ...

  6. for循环的三种写法

    第一种写法  传统的方法,遍历数组 String[] arr = { "amy", "heinrich", "cindy", "g ...

  7. 【WPF】无边框窗体

    之前写了一个支持尺寸变换的无边框窗体的一个基窗体,代码如下: public class LBaseWindow : Window { /// <summary> /// 基窗体 /// & ...

  8. WindowsPhone8解锁提示IpOverUsbSvc问题

    问题如图: 一般都是系统未启动或者未安装该服务. 1.使用sc命令查询是否存在IpOverUsbSvc服务 Cmd执行Sc query IpOverUsbSvc 结果如下,如果可以找到服务,state ...

  9. IC系统组成概论

    IC系统是什么? 对算法工程师来说,IC系统是完成特定功能的硬件.对架构设计师来说,IC系统包括控制,运算,存储部分.电路设计工程师来说,IC系统是加法器,乘法器,与非门,运算放大器,开关电容等的搭配 ...

  10. 微软职位内部推荐-Software Development Engineering II

    微软近期Open的职位: Job Title: Software Development Engineering II Work Location: Suzhou, China Enterprise ...