
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服務器成為可能。