近几日想在一个项目中引进一个Socket Server,用来接收客户端发送的命令消息并根据具体的业务逻辑对消息进行处理,然后转发给其它在线的客户端。因为以前在博客园关注过江大渔开源的SuperSocket,后来便在GithubCodeplex上一直关注该项目,但仅仅限于关注和了解。这次想通过具体的实践进一步学习该框架。我觉得一个优秀的开源项目离不开漂亮的代码、清晰的文档、完善的测试、持续的更新,当然从普通走向卓越更离不开社区的支持(源码、宣传、案例及文档等)。而SuperSocket对我个人而言是一个很优秀的开源项目,很值得去学习和应用。

官方介绍里,SuperSocket是一个轻量级、跨平台、可扩展的Socket应用框架。用户使用它可以很容易就构建出服务端Socket应用程序(如GPS Server、GIS Server、Game Server、FTP Server等),而不用去考虑关于Socket开发的具体细节(如socket如何使用,socket连接如何维护机器socket如何工作等)。常言“是骡子是马,拉出来溜溜”,看看官方实现提供的文档实例以及源码中的QuickStart系列,就可以发现使用SuperSocket开发一个socket server,真是很方便。鉴于个人能力的问题,关于SuperSocket的使用和理解可能有所偏差,本文所述均为个人理解笔记。

SuperSocket的基本认识

关于Server的一点想法

Server是用来响应请求的,Ngnix、Apache、IIS作为Web Server,Oracle、MySQL、MongoDB、SQLServer作为数据库Server,不同的角色决定了其拥有的功能和关注的痛点。比如Web Server主要是用来响应Http或Https协议的请求,其职责是尽可能快响应浏览器发出的请求(如图片、CSS、JS等静态文件的下载,表单数据的提交处理等),所以Server首先要专注的自己的核心任务所在,提供高性能、高质量服务。关于我自己项目中的Server需求很简单,仅仅是个消息的转发中心而已。

关于SuperSocket的数据处理流程的认识

编写Web应用程序的时候,对从浏览器到Server中间发生的故事的了解程度反应了一个人对整个Web开发的大局观,进而决定了所开发的程序的性能和质量。比如明白了请求从浏览器发出经由网卡进入互联网,经过多个路由转发跳转最后进入服务器端的Server,到了Server端又会进入各种处理管道,后面涉及到如数据库的访问、日志的记录查询等处理,再原路返回给客户端浏览器的过程,就理解了一个请求所耗费的各种时间,如路由器排队时间、网络传输时间、数据库访问时间、磁盘IO读写时间等等,也就能明白为什么各种各样的缓存是优化性能的最好帮手。君不见无论是应用程序中一个全局配置的单例缓存还是构建在Web Server与数据库之间的缓存服务器(Redis\Memcache),亦或是分布在祖国各地的CDN节点缓存,所有的缓存支持都是为了我们的Server提供更好的响应。

同样,使用Supersocket进行程序设计的时候,也得明白其数据流程是如何处理的。在官方的文档里面有一张图很好的说明了SuperSocket的请求处理流程:

在上图中很清晰的定位了SuperSocket Server所管辖的边界,由于网络中传输的数据包都是二进制流,如果是TCP还会有很多诸如粘包、拆包、组装等各种问题,但是使用SuperSocket可以完全忽略这些问题,因为SuperSocket帮我们很好的处理了这些问题。

  • 从连接请求到Session的创建: 当客户端与Server端的Socket监听端口成功建立连接后,SuperSocket Server就将该连接视为一个Session,它代表了客户端与Server端的逻辑连接,所有基于连接的操作都在Session中进行处理,比如收发数据、开关连接等;
  • 从二进制数据流到RequestInfo对象: 在SuperSocket中定义了两种对象,一种表示用户请求内容的RequestInfo实体类,每个来自客户端的请求都应该必须实例化成RequestInfo类型。但是网络中的二进制数据流如何映射成实体类呢?这就是Receive Filter的工作,将接收到的二进制数据转换成请求实例(RequestInfo),也就是在SuperSocket中通过Receive Filter进行协议解析,将数据流分割成一个个请求的实例对象。如果要实现自定义的协议很明显需要实现这两个东西,强悍的是SuperSocket已经内置了诸如结束符协议、固定数量分隔符协议、头部格式固定并且包含内容长度的协议等通用协议,对于我的项目已经绰绰有余了。

  • 从RequestInfo对象到响应服务: SuperSocket将服务抽象成一个个Command,其提供服务的方式也就是根据RequestInfo去执行响应的Command,然后再通过session将数据发送给客户端。由此可见,每一个Command必须包含两个东西那就是Session与RequestInfo。通过这种封装方式,很清晰的划分了各种职责边界,使得开发起来很舒服、很高效,更难能可贵的是测试很便捷。

  • 统管全局的AppServer对象: 前面分析了一个请求从发出到响应的整个流程,整个逻辑连接被视为一个AppSession,而AppServer就是管理Session对象的大Boss,是整个游戏的操控者。诸如Server的启动关闭,Session连接的管理(注册、注销、查询等),Receive Filter创建工厂的选择都是AppServer来实现的。总而言之一句话,这是AppServer的世界它做主。

SuperSocket的初步尝试

如果明白了上述流程,那么使用SuperSocket来开发就很简单了,再次梳理下相关的数据结构:

  1. AppServer:选择管理的Session类型、选择Server能够接受的RequestInfo请求实体类型、选择将二进制字节流转换成RequestInfo实体对象的Receive Filter的构建工厂,有了这些基本内容,Server就可以工作了;

  2. AppSesssion:Session只和数据流打交道,因此只需要选择相应的RequestInfo类型就可以,因为Session是运行在AppServer中的,所以此处的RequestInfo必须和AppServer选择的一致;

  3. RecieveFilter:它用来将二进制流转换成相应的RequestInfo对象实体,说白了也就是协议解析,因此它需要选择RequestInfo对象类型,然后实现ResolveRequestInfo的功能即可;

  4. Command:Server提供服务的方式,首先它需要通过Session与客户端进行交流,而交流的语言就是网络协议,也就是RequestInfo类型。

上述几个东西就是基于SuperSocket进行开发的核心所在,我说的选择其实就是指定泛型的具体类型。这样一来,如果我们需要完成一个自定义协议的socket Server,只需要按部就班的实现各个类型就OK了。

参考资料

  1. SuperSocket的官方文档;
  2. SuperSocket源码中的QuickStart;
  3. SuperSocket在Codeplex站点的文档;

开源项目SuperSocket的学习笔记的更多相关文章

  1. Android开源项目SlidingMenu本学习笔记(两)

    我们已经出台SlidingMenu使用:Android开源项目SlidingMenu本学习笔记(一个),接下来再深入学习下.依据滑出项的Menu切换到相应的页面 文件夹结构: watermark/2/ ...

  2. Android开源项目SlidingMenu的学习笔记(一)

    SlidingMenu是眼下在应用程序上非常流行的一种UI技术.能够实现一种比較炫的滑动效果,SlidingMenu是Git上托管的一个项目,开源免费的.SlidingMenu作为一个Library的 ...

  3. 开源规则引擎 Drools 学习笔记 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule

    直接进入正题 我们在使用开源规则引擎 Drools 的时候, 启动的时候可能会抛出如下异常: Caused by: java.lang.ClassCastException: cn.com.cheng ...

  4. Android开源项目分包方式学习(eoe、oschina、github)

    总感觉Android中关于分包的文章很少,或者几乎可以说没有.但是合理地分包,又可以使整个项目模块化,减少包与包之间的依赖,让整个项目的框架更加清晰,更利于后续功能的拓展. 因为没有相关的文章,所以这 ...

  5. hadoop data 相关开源项目(近期学习计划)

    计划学习几个hadoop相关的开源项目: 1.spring hadoop 2.spring batch 3.spring redis 4.spring mongo 相关项目样例:https://git ...

  6. java开源项目之IQQ学习记录之项目环境搭建与启动

    本文链接地址:http://blog.csdn.net/sushengmiyan/article/details/18779727 作者:sushengmiyan 现在就码字说说今天晚上搞定的一个项目 ...

  7. java开源项目之IQQ学习记录之单例模式与log4j日志记录

    作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/18992741 打开IQQ项目,打开包iqq.app中的 ...

  8. 创建第一个core项目(netCore学习笔记1)

    1.安装 core和netFramework其实是相对独立的,但是core的IDE是在vs2017才开始支持,而vs2017的安装环境必须搭配.net4.6,所以: Step1:安装.net4.6 S ...

  9. 开源流媒体服务器SRS学习笔记(2) - rtmp / http-flv / hls 协议配置 及跨域问题

    对rtmp/http-flv/hls这三种协议不熟悉的同学,强烈建议先看看网友写的这篇文章科普下:理解RTMP.HttpFlv和HLS的正确姿势 .   srs可以同时支持这3种协议,只要修改conf ...

随机推荐

  1. Windows下Sublime Text 默认打开方式问题解决办法

    注册表的解决办法: 删除 HKEY_CURRENT_USER\Software\Classes\Applications下的Sublime_Text.exe项.你就发现可以设置为默认打开方式了

  2. C#使用sharppcap实现网络抓包-----2

    虽然网上已经有了SharpSniffer 这一个SharpSniffer还是原创的无他,唯为学习工程文件下载:SharpSniffer.rar 1.创建套接字2.绑定到本机3.设置IOControl4 ...

  3. POJ 3468 A Simple Problem with Integers(树状数组)

    题目链接:http://poj.org/problem?id=3468 题意:给出一个数列,两种操作:(1)将区间[L,R]的数字统一加上某个值:(2)查询区间[L,R]的数字之和. 思路:数列A,那 ...

  4. git终端提示符

    最近使用git bash的时候,看到默认的终端提示符不爽,主要是太长了.所以想对git终端提示符进行优化 默认git的终端提示符会是  用户名@设备名称 ,我想改成更短的来查看. 提示符是由一个环境变 ...

  5. gulp 使用mailgun服务器发送邮件

    1.首先你需要创建一个 mailgun 账户,没有请去注册一个. 注册之后会有 mailgun 会给你一个默认的子域名,你就可以使用这个子域名去发送邮件了,如下图: 2.gulp创建任务: var s ...

  6. Android动画效果translate、scale、alpha、rotate

    overridePendingTransition只支持android 2.0以上版本,动画效果在anim目录下的xml文件中定义,在程序中用AnimationUtils.loadAnimation( ...

  7. 函数buf_LRU_add_block

    /******************************************************************//** Adds a block to the LRU list ...

  8. ASP.NET MVC 学习3、Controller左手从Model获取数据,右手传递到View页面

    参考:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/accessing-your-models-dat ...

  9. Lost connection to MySQL server at 'reading initial communication packet' 错误解决

    Lost connection to MySQL server at 'reading initial communication packet' 错误解决 上次解决了这个问题,今天又碰到,突然失忆, ...

  10. HDU 1269 迷宫城堡 (强连通分量,常规)

    题意: 判断所给的有向图是否是一个强连通图. 思路: 如果连通分量大于1则必定No,如果强连通分量大于1也是No.tarjan算法求强连通分量. #include <cstdio> #in ...