




已阅读5页,还剩43页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
SuperSocket 是一个轻量级的可扩展的 Socket 开发框架,可用来构建一个服务器端 Socket 程序,而无需了解如何使用 Socket,如何维护Socket连接,Socket是如何工作的。该项目使用纯 C# 开发,易于扩展和集成到已有的项目。只要你的已有系统是使用.NET开发的,你都能够使用 SuperSocket来轻易的开发出你需要的Socket应用程序来集成到你的现有系统之中。SuperSocket具有如下特点: 简单易用,只需要几个类就能创建出健壮的Socket服务器端程序 性能优良, 稳定可靠 支持各种协议, 内置的协议解析工具让你把实现通信协议这种复杂的工作变得很简单 自动支持SSL/TLS传输层加密 强大,灵活而且可扩展的配置让你开发Socket服务器省时省力 支持多个socket服务器实例运行, 而且支持多个服务器实例的隔离 SuperSocket能以控制台或者Windows服务形式运行。一个脚本就能将SuperSocket安装成服务 灵活的日志策略能够记录大部分socket活动 支持UDP 支持IPv6 支持Windows Azure 支持Linux/Unix操作系统(通过Mono 2.10或以上版本) 内置可直接使用的Flash/Silverlight Socket策略服务器AppSession 代表一个和客户端的逻辑连接,基于连接的操作应该定于在该类之中。你可以用该类的实例发送数据到客户端,接收客户端发送的数据或者关闭连接。AppServer 代表了监听客户端连接,承载TCP连接的服务器实例。理想情况下,我们可以通过AppServer实例获取任何你想要的客户端连接,服务器级别的操作和逻辑应该定义在此类之中。实现你自己的AppSession和AppServer允许你根据你业务的需求来方便的扩展SuperSocket,你可以绑定session的连接和断开事件,服务器实例的启动和停止事件。你还可以在AppServer的Setup方法中读取你的自定义配置信息。总而言之,这些功能让你方便的创建一个你所需要的socket服务器成为可能。通过配置启动: 避免硬编码 SuperSocket提供了很多有用的配置选项 可以充分利用SuperSocket提供的工具内置的命令行协议内置的命令行协议(接受自定义,分隔符为“:”,“,”):命令行协议定义了每个请求必须以回车换行结尾 rn。由于 SuperSocket 中内置的命令行协议用空格来分割请求的Key和参,因此当客户端发送如下数据到服务器端时:LOGIN kerry 123456 + NewLineSuperSocket 服务器将会收到一个 StringRequestInfo 实例,这个实例的属性为:Key: LOGINBody: kerry 123456;Parameters: kerry, 123456SuperSocket 提供了一些通用的协议解析工具, 你可以用他们简单而且快速的实现你自己的通信协议TerminatorReceiveFilterFactory:一个协议使用两个字符 # 作为结束符“CountSpliterReceiveFilter”: 有些协议定义了像这样格式的请求 #part1#part2#part3#part4#part5#part6#part7#. 每个请求有7个由 # 分隔的部分. 这种协议的实现非常简单:“FixedSizeReceiveFilter”:在这种协议之中, 所有请求的大小都是相同的。如果你的每个请求都是有9个字符组成的字符串,如KILL BILL, 你应该做的事就是想如下代码这样实现一个接收过滤器(ReceiveFilter):“BeginEndMarkReceiveFilter”:在这类协议的每个请求之中 都有固定的开始和结束标记。例如, 我有个协议,它的所有消息都遵循这种格式 !xxxxxxxxxxxxxx$。因此,在这种情况下, ! 是开始标记, $ 是结束标记,于是你的接受过滤器可以定义成这样:“FixedHeaderReceiveFilter”:这种协议将一个请求定义为两大部分, 第一部分定义了包含第二部分长度等等基础信息. 我们通常称第一部分为头部.例如, 我们有一个这样的协议: 头部包含 6 个字节, 前 4 个字节用于存储请求的名字, 后两个字节用于代表请求体的长度:你需要基于类FixedHeaderReceiveFilter实现你自己的接收过滤器.然后你就可以使用接收或者自己定义的接收过滤器工厂来在 SuperSocket 中启用该协议.在.NET中的反射也可以实现从对象的外部来了解对象(或程序集)内部结构的功能,哪怕你不知道这个对象(或程序集)是个什么东西,另外.NET中的反射还可以运态创建出对象并执行它其中的方法。这一块的内容负责让自定义的协议开始工作:通信协议用于将接收到的二进制数据转化成您的应用程序可以理解的请求。 SuperSocket提供了一个内置的通信协议“命令行协议”定义每个请求都必须以回车换行rn结尾。但是一些应用程序无法使用命令行协议由于不同的原因。 这种情况下,你需要使用下面的工具来实现你的自定义协议:* RequestInfo* ReceiveFilter* ReceiveFilterFactory* AppServer and AppSession请求(RequestInfo)请求类型 StringRequestInfo 用在 SuperSocket 命令行协议中。你也可以根据你的应用程序的需要来定义你自己的请求类型。 例如, 如果所有请求都包含 DeviceID 信息,你可以在RequestInfo类里为它定义一个属性SuperSocket 还提供了另外一个请求类 BinaryRequestInfo 用于二进制协议:接收过滤器(ReceiveFilter)接收过滤器(ReceiveFilter)用于将接收到的二进制数据转化成请求实例(RequestInfo)。实现一个接收过滤器(ReceiveFilter), 你需要实现接口 IReceiveFilter:public interface IReceiveFilter where TRequestInfo : IRequestInfo / / Filters received data of the specific session into request info. / / 待读取的缓冲数据. / 这个待读取缓冲中当前接收数据的偏移量 / 当前接收数据的长度 / if set to true to be copied. / 没有被解析的数据的长度 / TRequestInfo Filter(byte readBuffer, int offset, int length, bool toBeCopied, out int rest); / / Gets the size of the left buffer. / / / 接收过滤器已缓存数据的长度/ int LeftBufferSize get; / / Gets the next receive filter. / IReceiveFilter NextReceiveFilter get; / / Resets this instance to initial state.重置这个实例到初始化状态 / void Reset();TRequestInfo: 类型参数 TRequestInfo 是你要在程序中使用的请求类型(RequestInfo);LeftBufferSize: 该接收过滤器已缓存数据的长度;NextReceiveFilter: 当下一块数据收到时,用于处理数据的接收过滤器实例;Reset(): 重设接收过滤器实例到初始状态;Filter(.): 该方法将会在 SuperSocket 收到一块二进制数据时被执行,接收到的数据在 readBuffer 中从 offset 开始, 长度为 length 的部分。TRequestInfo Filter(byte readBuffer, int offset, int length, bool toBeCopied, out int rest);readBuffer: 接收缓冲区, 接收到的数据存放在此数组里offset: 接收到的数据在接收缓冲区的起始位置length: 本轮接收到的数据的长度toBeCopied: 表示当你想缓存接收到的数据时,是否需要为接收到的数据重新创建一个备份而不是直接使用接收缓冲区rest: 这是一个输出参数, 它应该被设置为当解析到一个为正的请求后,接收缓冲区还剩余多少数据未被解析这儿有很多种情况需要你处理:当你在接收缓冲区中找到一条完整的请求时,你必须返回一个你的请求类型的实例.当你在接收缓冲区中没有找到一个完整的请求时, 你需要返回 NULL.当你在接收缓冲区中找到一条完整的请求, 但接收到的数据并不仅仅包含一个请求时,设置剩余数据的长度到输出变量 rest. SuperSocket 将会检查这个输出参数 rest, 如果它大于 0, 此 Filter 方法 将会被再次执行, 参数 offset 和 length 会被调整为合适的值.接收过滤器工厂(ReceiveFilterFactory)接收过滤器工厂(ReceiveFilterFactory)用于为每个会话创建接收过滤器. 定义一个过滤器工厂(ReceiveFilterFactory)类型, 你必须实现接口 IReceiveFilterFactory. 类型参数 TRequestInfo 是你要在整个程序中使用的请求类型/ / Receive filter factory interface/ / 定义的请求类型 public interface IReceiveFilterFactory : IReceiveFilterFactory where TRequestInfo : IRequestInfo / / 创建接收过滤器 / / The app server. / The app session. / 远程端点. / / the new created request filer assosiated with this socketSession/新建的请求过滤器与SocketSession产生关联 / IReceiveFilter CreateFilter(IAppServer appServer, IAppSession appSession, IPEndPoint remoteEndPoint);你也可以直接使用默认的过滤器工厂(ReceiveFilterFactory)DefaultReceiveFilterFactory, 当工厂的CreateFilter方法被调用时,它将会调用TReceiveFilter类型的无参构造方法来创建并返回TReceiveFilter.和 AppSession,AppServer 配合工作现在, 你已经有了 RequestInfo, ReceiveFilter 和 ReceiveFilterFactory, 但是你还没有正式使用它们. 如果你想让他们在你的程序里面可用, 你需要定义你们的 AppSession 和 AppServer 来使用他们.1.为 AppSession 设置 RequestInfopublic class YourSession : AppSession /More code.2.为 AppServer 设置 RequestInfo 和 ReceiveFilterFactorypublic class YourAppServer : AppServer public YourAppServer() : base(new YourReceiveFilterFactory() 完成上面两件事情,你的自定义协议就应该可以工作了。命令和命令加载器关键字: 命令, 命令加载器, 多命令程序集命令 (Command)SuperSocket 中的命令设计出来是为了处理来自客户端的请求的, 它在业务逻辑处理之中起到了很重要的作用。命令类必须实现下面的基本命令接口:public interface ICommand : ICommand where TRequestInfo : IRequestInfo where TAppSession : IAppSession void ExecuteCommand(TAppSession session, TRequestInfo requestInfo);public interface ICommand string Name get; 请求处理代码必须被放置于方法 ExecuteCommand(TAppSession session, TRequestInfo requestInfo) 之中,并且属性 Name 的值用于匹配接收到请求实例(requestInfo)的Key。当一个请求实例(requestInfo) 被收到时,SuperSocket 将会通过匹配请求实例(requestInfo)的Key和命令的Name的方法来查找用于处理该请求的命令。举个例子, 如果你收到如下请求(requestInfo):Key: ADDBody: 1 2于是 SuperSocket 将会寻找Name属性为ADD的命令。如果有个命令定义如下:public class ADD : StringCommandBase public override void ExecuteCommand(AppSession session, StringRequestInfo requestInfo) session.Send(int.Parse(requestInfo0 + int.Parse(requestInfo1).ToString(); 因为基类 StringCommandBase 会设置Name属性的值为此类的名称(ADD),因此个命令将会被找到.但是在有些情况, 请求实例(requestInfo)的Key 无法当做类的名称。 比如说:Key: 01Body: 1 2为了让让你的 ADD 命令起作用,你需要为命令类重写Name属性:public class ADD : StringCommandBase public override string Name get return 01; public override void ExecuteCommand(AppSession session, StringRequestInfo requestInfo) session.Send(int.Parse(requestInfo0 + int.Parse(requestInfo1).ToString(); 命令程序集定义是的,SuperSocket是用反射来查找哪些公开的类实现了基本的命令接口,但是它只在你的AppServer类定义的程序集中查找。举例来说, 你的 AppServer 定义在程序集 GameServer.dll 中, 但是你的 ADD 命令是定义在程序集 BasicModules.dll 中:GameServer.dll + MyGameServer.csBasicModules.dll + ADD.cs默认的, 命令 ADD 将不会被加载到游戏服务器实例。 如果你想要加载该命令, 你如要在配置中添加程序集 BasicModules.dll 到命令程序集列表之中: 当然你也可以在配置中添加多个命令程序集。命令加载器 (Command Loader)在某些情况下,你可能希望通过直接的方式来加载命令,而不是通过自动的反射。 如果是这样,你可以实现你自己的命令加载器 (Command Loader):public interface ICommandLoader然后配置你的服务器来使用你新建的命令加载器 (Command Loader): 获取会话的连接和断开事件关键字: 连接事件, 断开事件, OnSessionStarted, OnSessionClosed, NewSessionConnected, SessionClosedAppSession 的虚方法 OnSessionStarted() 和 OnSessionClosed(CloseReason reason)你可以覆盖基类的虚方法 OnSessionStarted() 和 OnSessionClosed(CloseReason reason) 用于在会话连接和断开时执行一些逻辑操作:public class TelnetSession : AppSession protected override void OnSessionStarted() this.Send(Welcome to SuperSocket Telnet Server); /add your business operations protected override void OnSessionClosed(CloseReason reason) /add your business operations AppServer 的两个事件: NewSessionConnected 和 SessionClosed订阅事件:appServer.NewSessionConnected += new SessionHandler(appServer_NewSessionConnected);appServer.SessionClosed += new SessionHandler(appServer_SessionClosed);定义事件处理方法:static void appServer_SessionClosed(AppSession session, CloseReason reason) Console.WriteLine(A session is closed for 0., reason);static void appServer_NewSessionConnected(AppSession session) session.Send(Welcome to SuperSocket Telnet Server);主动从服务器端推送数据到客户端关键字: 主动推送, 推送数据, 客户端推送, 获取Session, 发送数据, 回话快照通过Session对象发送数据到客户端前面已经说过,AppSession 代表了一个逻辑的 socket 连接,基于连接的操作都应该定义在此类之中。 这个AppSession 类也封装了通过 socket 发送数据的方法。 你可以使用 AppSession 的方法 Send(.) 来发送数据到客户端:session.Send(data, 0, data.Length);orsession.Send(Welcome to use SuperSocket!);通过 SessionID 获取 Session前面提到过,如果你获取了连接的 Session 实例,你就可以通过 Send() 方法向客户端发送数据。但是在某些情况下,你无法直接获取 Session 实例。SuperSocket 提供了一个 API 让你从 AppServer 的 Session 容器中通过 SessionID 获取 Sessionvar session = appServer.GetSessionByID(sessionID);if(session != null) session.Send(data, 0, data.Length);SessionID是什么?SessionID 是 AppSession 类的一个属性,用于唯一标识一个 Session 实例。 在一个 SuperSocket TCP 服务器中,当 Session 一创建, SessionID 就会被赋值为一个 GUID 字符串。 如果你不在 SuperSocket UDP 服务器中使用 UdpRequestInfo,SessionID 就会有客户端的IP和端口组成。 如果你使用UdpRequestInfo,SessionID将会从客户端传过来。获取所有连接上的 Session你也可以从 AppServer 实例获取所有连接上的 session 然后推送数据到所有客户端:foreach(var session in appServer.GetAllSessions() session.Send(data, 0, data.Length); 如果你启用了 Session 快照, 这些从 AppServer.GetAllSessions() 获取的 sessions 将不是实时更新的。 他们是在上次获取快照时所有连接到服务器的 Session。 快照相关配置,请参考配置文档。根据条件获取 Session如果你有一个自定义的属性 CompanyId 在你的 AppSession 类之中,如果你想要获取这个属性等于某值的 的所有 Session, 你可以使用 AppServer 的方法 GetSessions(.):var sessions = appServer.GetSessions(s = s.CompanyId = companyId);foreach(var s in sessions) s.Send(data, 0, data.Length);和方法 GetAllSessions(.) 一样, 如果你启用了 Session 快照,这些返回的 session 也一样也来自于快照之中。扩展服务器配置关键字: 扩展配置, 自定义配置, 自定义属性, GetChildConfig, 读取配置,子节点当你使用 SuperSocket 实现 Socket 服务器的时候,不可避免的需要在配置文件中定义一些参数。 SuperSocket 提供了非常简单的方法,让你在配置文件中定义这些参数,然后在你的代码中读取它们。请看下面的配置代码:在上面的配置中, 属性 policyFile 未在 SuperSocket 中定义, 不过你任然可以在你的 AppServer 类中读取它:public class YourAppServer : AppServer private string m_PolicyFile; protected override bool Setup(IRootConfig rootConfig, IServerConfig config) m_PolicyFile = config.Options.GetValue(policyFile); if (string.IsNullOrEmpty(m_PolicyFile) if(Logger.IsErrorEnabled) Logger.Error(Configuration option policyFile is required!); return false; return true; 你不仅可以在 server 节点定义属性, 而且你还能像下面的代码那样定义子节点: 下面是所需的节点对应的配置类:/ / SubProtocol configuration/ public class SubProtocolConfig : ConfigurationElement /Configuration attributes/ / SubProtocol configuation collection/ ConfigurationCollection(typeof(SubProtocolConfig)public class SubProtocolConfigCollection : ConfigurationElementCollection /Configuration attributes然后你就能在 AppServer 类中读取这个子节点了:public class YourAppServer : AppServer private SubProtocolConfigCollection m_SubProtocols; protected override bool Setup(IRootConfig rootConfig, IServerConfig config) m_SubProtocols = config.GetChildConfig(subProtocols); if (m_SubProtocols = null) if(Logger.IsErrorEnabled) Logger.Error(The child configuration node subProtocols is required!); return false; return true; 服务器配置热更新Keywords: 配置,热更新此功能能够允许你在不重启服务器的前提下更新服务器实例的配置。 (仅限1.6.5及其以上版本)支持热更新的服务器实例配置选项SuperSocket 支持以下配置选项的热更新:* logCommand* idleSessionTimeOut* maxRequestLength* logBasicSessionActivity* logAllSocketExceptionSuperSocket 支持所有自定义配置属性和自定义配置子节点的热更新。下面的代码将演示如何让你的自定义配置支持热更新:public class PushServer : AppServer private int m_Interval; protected override bool Setup(IRootConfig rootConfig, IServerConfig config) RegisterConfigHandler(config, pushInterval, (value) = / the code in this scope will be executed automatically / after the configuration attribute pushInterval is changed var interval = 0; int.TryParse(value, out interval); if (interval = 0) interval = 60;/ 60 seconds by default m_Interval = interval * 1000; return true; ); return true; / Other code你可以在QuickStart中的 PushServer 项目中找到此更能的完整示例代码。命令过滤器关键字: 命令过滤器, 命令, 过滤器, OnCommandExecuting, OnCommandExecutedSuperSocket 中的命令过滤器看起来有些像 ASP.NET MVC 中的 Action Filter,你可以用它来做命令执行的拦截,命令过滤器会在命令执行前和执行后被调用。命令过滤器必须继承于 Attribute 类 CommandFilterAttribute: / / Command filter attribute/ AttributeUsage(AttributeTargets.Class, AllowMultiple = true)public abstract class CommandFilterAttribute : Attribute / / Gets or sets the execution order. / / / The order. / public int Order get; set; / / Called when command executing. / / The command context. public abstract void OnCommandExecuting(CommandExecutingContext commandContext); / / Called when command executed. / / The command context. public abstract void OnCommandExecuted(CommandExecutingContext commandContext);你需要为你的命令过滤器实现下面两个方法:OnCommandExecuting: 此方法将在命令执行前被调用;OnCommandExecuted: 此方法将在命令执行后被调用;Order: 此属性用于设置多个命令过滤器的执行顺序;下面的代码定义了一个命令过滤器 LogTimeCommandFilterAttribute 用于记录执行时间超过5秒钟的命令:public class LogTimeCommandFilter : CommandFilterAttribute public override void OnCommandExecuting(CommandExecutingContext commandContext) commandContext.Session.ItemsStartTime = DateTime.Now; public override void OnCommandExecuted(CommandExecutingContext commandContext) var session = commandContext.Session; var startTime = session.Items.
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中国虾罟网行业投资前景及策略咨询研究报告
- 2025年中国脂肪称重仪行业投资前景及策略咨询研究报告
- 2025年中国纤维计量混合装置行业投资前景及策略咨询研究报告
- 2025年中国移动多媒体数字车行业投资前景及策略咨询研究报告
- 2025年中国盆栽兰花行业市场调查、投资前景及策略咨询报告
- 2025年中国电厂输送网带行业市场调查、投资前景及策略咨询报告
- 2025年中国燃气调压流量计行业投资前景及策略咨询研究报告
- 2025年中国液压式安全联轴器行业投资前景及策略咨询研究报告
- 2025年中国汽车悬挂配件行业投资前景及策略咨询研究报告
- 2025年中国椭圆型陶瓷内胆行业市场调查、投资前景及策略咨询报告
- 一例高血压合并糖尿病患者的个案护理课件
- 2025年中考地理务必掌握的答题思路与模板
- 临时占地免责协议书
- 工会法律知识培训课件
- 档案管理员实操能力考试题试题及答案
- 供应链风险管理知识点及试题及答案
- 隐患排查五定制度
- BRCGS全球标准食品安全第9版标准要求
- 北京市初中《体育与健康知识》学业水平考试复习题库及答案
- 教师口语知到智慧树章节测试课后答案2024年秋成都师范学院
- 2024年福州第十一中学招聘笔试真题
评论
0/150
提交评论