首页 > 代码库 > SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config
SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SuperSocket.Common; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Protocol; /**************************************************************** * 作者:黄昏前黎明后 * CLR版本:4.0.30319.42000 * 创建时间:2017-01-19 00:02:17 * 2017 * 描述说明:自定义连接类MySession,继承AppSession,并传入到AppSession * * 修改历史: * * *****************************************************************/ namespace SuperSocketDemo.Session { /// <summary> /// 自定义连接类MySession,继承AppSession,并传入到AppSession /// </summary> public class MySession : AppSession<MySession> { /// <summary> /// 新连接 /// </summary> protected override void OnSessionStarted() { //输出客户端IP地址 Console.WriteLine(this.LocalEndPoint.Address.ToString()); this.Send("Hello User,Welcome to SuperSocket Telnet Server!"); } /// <summary> /// 未知的Command /// </summary> /// <param name="requestInfo"></param> protected override void HandleUnknownRequest(StringRequestInfo requestInfo) { this.Send("unknow"); } /// <summary> /// 捕捉异常并输出 /// </summary> /// <param name="e"></param> protected override void HandleException(Exception e) { this.Send("error: {0}", e.Message); } /// <summary> /// 连接关闭 /// </summary> /// <param name="reason"></param> protected override void OnSessionClosed(CloseReason reason) { base.OnSessionClosed(reason); } } }
using SuperSocket.SocketBase; using SuperSocket.SocketBase.Config; using SuperSocketDemo.Session; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; /**************************************************************** * 作者:黄昏前黎明后 * CLR版本:4.0.30319.42000 * 创建时间:2017-01-19 00:15:45 * 2017 * 描述说明:自定义服务器类MyServer,继承AppServer,并传入自定义连接类MySession * * 修改历史: * * *****************************************************************/ namespace SuperSocketDemo.Server { /// <summary> /// 自定义服务器类MyServer,继承AppServer,并传入自定义连接类MySession /// </summary> public class MyServer : AppServer<MySession> { protected override void OnStartup() { base.OnStartup(); // Console.WriteLine("服务器启动"); } /// <summary> /// 输出新连接信息 /// </summary> /// <param name="session"></param> protected override void OnNewSessionConnected(MySession session) { base.OnNewSessionConnected(session); //输出客户端IP地址 Console.Write("\r\n" + session.LocalEndPoint.Address.ToString() + ":连接"); } /// <summary> /// 输出断开连接信息 /// </summary> /// <param name="session"></param> /// <param name="reason"></param> protected override void OnSessionClosed(MySession session, CloseReason reason) { base.OnSessionClosed(session, reason); Console.Write("\r\n" + session.LocalEndPoint.Address.ToString() + ":断开连接"); } protected override void OnStopped() { base.OnStopped(); Console.WriteLine("服务已停止"); } } }
public class Hello: CommandBase<MySession, StringRequestInfo> { /// <summary> /// 自定义执行命令方法,注意传入的变量session类型为MySession /// </summary> /// <param name="session">会话</param> /// <param name="requestInfo">请求数据信息</param> public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo) { session.Send(string.Format("Hello {0}:{1} {2}", session.Config.Ip, session.Config.Port, requestInfo.Body)); } }
定义一个名为"ADD"的类去处理Key为"ADD"的请求:
public class ADD : CommandBase<MySession, StringRequestInfo> { public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo) { session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString()); } }
定义一个名为"MULT"的类去处理Key为"MULT"的请求:
public class MULT : CommandBase<MySession, StringRequestInfo> { public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo) { var result = 1; foreach (var factor in requestInfo.Parameters.Select(p => Convert.ToInt32(p))) { result *= factor; } session.Send(result.ToString()); } }
public class Echo: CommandBase<MySession, StringRequestInfo> { public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo) { session.Send(requestInfo.Body); } }
同时我们要移除请求处理方法的注册,因为它和命令不能同时被支持,注释下面代码即可
//appServer.NewRequestReceived += new RequestHandler<MySession, StringRequestInfo>(appServer_NewRequestReceived);
4、配置App.config使用BootStrap启动SuperSocket
SuperSocket配置section SuperSocket使用.NET自带的配置技术,SuperSocket有一个专门的配置Section.使用配置启动SuperSocket可以灵活配置选项
配置完成后,还需要修改program类。将原有在program中定义的端口信息以及方法注释,只保留服务启动和停止的代码。引入using SuperSocket.SocketEngine;使用BootStrap启动
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Protocol; using SuperSocket.SocketEngine; using SuperSocketDemo.Server; /**************************************************************** * 作者:黄昏前黎明后 * CLR版本:4.0.30319.42000 * 创建时间:2017-01-19 00:02:17 * 2017 * 描述说明:服务启动和停止入口 * * 修改历史: 2017 -01-19 调整自定义mysession和myserver * * *****************************************************************/ namespace SuperSocketDemo { class Program { /// <summary> /// SuperSocket服务启动或停止 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Console.WriteLine("请按任何键进行启动SuperSocket服务!"); Console.ReadKey(); Console.WriteLine(); var bootstrap = BootstrapFactory.CreateBootstrap(); if (!bootstrap.Initialize()) { Console.WriteLine("初始化失败!"); Console.ReadKey(); return; } //修改appserver为myserver //var appServer = new AppServer(); // var appServer = new MyServer(); //注册事件 // appServer.NewSessionConnected += new SessionHandler<AppSession>(appServer_NewSessionConnected); //appServer.NewRequestReceived += new RequestHandler<AppSession, StringRequestInfo>(appServer_NewRequestReceived); //设置端口号 //int port = 2017; //启动应用服务端口 //if (!appServer.Setup(port)) //启动时监听端口2017 //{ // Console.WriteLine("服务端口启动失败!"); // Console.ReadKey(); // return; //} //Console.WriteLine(); ////尝试启动应用服务 //if (!appServer.Start()) //{ // Console.WriteLine("服务启动失败!"); // Console.ReadKey(); // return; //} var result = bootstrap.Start(); Console.WriteLine("服务正在启动: {0}!", result); if (result == StartResult.Failed) { Console.WriteLine("服务启动失败!"); Console.ReadKey(); return; } Console.WriteLine("服务启动成功,请按‘E‘停止服务!"); while (Console.ReadKey().KeyChar != ‘E‘) { Console.WriteLine(); continue; } //停止服务 // appServer.Stop(); bootstrap.Stop(); Console.WriteLine("服务已停止!"); Console.ReadKey(); } /// <summary> /// 在事件处理代码中发送欢迎信息给客户端 /// </summary> /// <param name="session"></param> //static void appServer_NewSessionConnected(AppSession session) //{ // session.Send("Welcome to SuperSocket Telnet Server!"); //} /// <summary> ///客户端请求处理 /// </summary> /// <param name="session">会话</param> /// <param name="requestInfo">请求信息</param> //static void appServer_NewRequestReceived(AppSession session, StringRequestInfo requestInfo) //{ // switch (requestInfo.Key.ToUpper()) // { // case ("ECHO"): // session.Send(requestInfo.Body); // break; // case ("ADD"): // session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString()); // break; // case ("MULT"): // var result = 1; // foreach (var factor in requestInfo.Parameters.Select(p => Convert.ToInt32(p))) // { // result *= factor; // } // session.Send(result.ToString()); // break; // } //} } }
最后我们看一下修改后程序的运行结果:
断开调试工具看一下效果,可以看到服务端显示客户端断开连接
注意事项:
总结:
通过自定义Session和Server,可以实现我们自己的AppSession和AppServer允许你根据你业务的需求来方便的扩展SuperSocket,你可以绑定session的连接和断开事件,服务器实例的启动和停止事件。你还可以在AppServer的Setup方法中读取你的自定义配置信息。总而言之,这些功能让你方便的创建一个你所需要的socket服务器成为可能。
SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config