一种仿照Asp.net Mvc思维构建WebSocket服务器的方法
问题场景
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服务器的方法的更多相关文章
- ASP.NET MVC 5 - 查询Details和Delete方法
在这部分教程中,接下来我们将讨论自动生成的Details和Delete方法. 查询Details和Delete方法 打开Movie控制器并查看Details方法. public ActionResul ...
- [转]ASP.NET MVC 5 - 查询Details和Delete方法
在这部分教程中,接下来我们将讨论自动生成的Details和Delete方法. 查询Details和Delete方法 打开Movie控制器并查看Details方法. public ActionResul ...
- asp.net MVC webservice 报次错解决方法
asp.net MVC webservice 报次错解决方法: 解决方法: 在 RouteConfig.cs public static void RegisterRoutes(RouteCol ...
- T4 模板 : 一种提升ASP.NET MVC开发速度方法
最近由于需要在框架中提供一些自定义模板的功能,找到了一篇博客,可惜似乎是翻译工具直接翻的,读不通顺,就试着自己翻译下,我不会完全翻译原文的句子,可能会对原文进行小范围的我认为更合适的句子并添加些注释, ...
- 测试驱动 ASP.NET MVC 和构建可测试 ASP.NET MVC 应用程序
[测试驱动 ASP.NET MVC] http://t.cn/8kdi4Wl [构建可测试 ASP.NET MVC 应用程序]http://t.cn/8kdi4Wj
- ASP.NET MVC 实现AJAX跨域请求方法《1》
ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...
- Asp.net MVC 中超链接的三个方法及比较
在Asp.net WebForm开发中,我们通过a标签进行跳转时,通常的写法是:<a href="index.aspx">首页</a>, 在Asp.net ...
- asp.net mvc webapi 实用的接口加密方法
在很多项目中,因为webapi是对外开放的,这个时候,我们就要得考虑接口交换数据的安全性. 安全机制也比较多,如andriod与webapi 交换数据的时候,可以走双向证书方法,但是开发成本比较大, ...
- asp.net mvc webapi 实用的接口加密方法(转载)
在很多项目中,因为webapi是对外开放的,这个时候,我们就要得考虑接口交换数据的安全性. 安全机制也比较多,如andriod与webapi 交换数据的时候,可以走双向证书方法,但是开发成本比较大, ...
随机推荐
- java工程中的相关路径
一.路径 绝对路径: 指的是文件在系统中的真实路径(物理路径). 相对路径: 指的是文件相对某个目录的相对路径. 对于java application 工程来说,当编写完一个类之后,class文件会编 ...
- Tomcat 服务器版本的区别以及下载与安装
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun 和其他一些公司及个人共同开发而成.由于有了 ...
- mysql、sql server、oracle数据库分页查询及分析(操作手册)
1.mysql分页查询 方式1: select * from table order by id limit m, n; 该语句的意思为,查询m+n条记录,去掉前m条,返回后n条记录.无疑该查询能够实 ...
- linux chromuim安装常用插件(flash,手势,拖拽,广告屏蔽)
1.本机kali2.0 64位,kali基于Debian.文章所用的所有插件请到http://files.cnblogs.com/files/yuuyuu/chromium_plugins.tar. ...
- Python 基本类型转换
python 有关字符串处理有哪些好用的方法?reverse len 字符串分割,合并?截取?查找? find index join split unicode字符串的表示 ""& ...
- selenium读取txt文件的几种方式
1.用java读取txt文件 public static String readFJ(String path) { path = "D:/workspace/hetong.txt" ...
- ADS(一)
LC匹配 已知输入输出阻抗,设计LC匹配电路使输入输出阻抗共轭匹配 Step1 Step2 Result1 Result2 微带线单枝匹配 已知源和负载阻抗,求微带线单枝匹配电路 Step1 ...
- [转载]ExtJs4 笔记(10) Ext.tab.Panel 选项卡
作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)版权声明:本文的版权归作者与博客园共有.转载时须注明本文的详细链接,否则作者将保留追究其法律 ...
- Codeforces Round #253 Div2 D.Andrey and Problem 概率+贪心
概率计算:P(某set) = 令: 和 现在考虑: 1.考虑某个集合,再加一个概率为Pi的朋友后能不能使总概率提高. 即: 由公式可知, 如果 S < 1,则delta > 0,则 ...
- HDU 2602 Bone Collector --01背包
这种01背包的裸题,本来是不想写解题报告的.但是鉴于还没写过背包的解题报告.于是来一发. 这个真的是裸的01背包. 代码: #include <iostream> #include < ...