近几日想在一个项目中引进一个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. 68. Text Justification

    题目: Given an array of words and a length L, format the text such that each line has exactly L charac ...

  2. 开源入侵检测系统OSSEC搭建之二:客户端安装

    上一篇文章中已经将OSSEC服务端的安装以及客户端的Key导出操作做了解说,接下来在另一台虚拟机中安装客户端,与安装服务端类似同样需要安装ossec,步骤如下. 一.下载ossec-hids-2.8. ...

  3. Linux文件目录结构详解

    整理自<鸟哥的私房菜> 对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于 ...

  4. tcpdump抓SQL

    前言:假设如果有个服务器几十个链接突然达到上千个链接,show processlist,general_log,还有慢查询日志这些都不能用,你怎么把这些链接过来的SQL情况了解清楚,如果你觉得那些好用 ...

  5. JVM学习笔记(四)------内存调优

    首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提 ...

  6. 分批次获取git for windows的源代码

    $ git initInitialized empty Git repository in d:/SourceCode/GitHub/Git For Windows/Git/.git/ $ git r ...

  7. 1493: [NOI2007]项链工厂

    线段树. 真还就是个线段树.. 除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2.(这点没想到).. 我们用一个delta维护操作1,如果没有旋转就+k,不然就-k. 每次读入i和 ...

  8. UVa 1475 (二分+半平面交) Jungle Outpost

    题意: 有n个瞭望塔构成一个凸n边形,敌人会炸毁一些瞭望台,剩下的瞭望台构成新的凸包.在凸多边形内部选择一个点作为总部,使得敌人需要炸毁的瞭望塔最多才能使总部暴露出来.输出敌人需要炸毁的数目. 分析: ...

  9. Only one instance of a ScriptManager can be added to the page.

    一般出现在一个页面用了多个用户控件,而每个用户控件中都用到了ScriptManager,最好的办法是控件中不要加上         <asp:ScriptManager ID="Scr ...

  10. Oracle表与索引的分析及索引重建

    1.分析表与索引(analyze 不会重建索引)   analyze table tablename compute statistics 等同于 analyze table tablename co ...