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"的請求:bootstrap
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); } }
同時咱們要移除請求處理方法的註冊,由於它和命令不能同時被支持,註釋下面代碼便可session
//appServer.NewRequestReceived += new RequestHandler<MySession, StringRequestInfo>(appServer_NewRequestReceived);app
四、配置App.config使用BootStrap啓動SuperSocket框架
SuperSocket配置section SuperSocket使用.NET自帶的配置技術,SuperSocket有一個專門的配置Section.使用配置啓動SuperSocket能夠靈活配置選項socket
配置完成後,還須要修改program類。將原有在program中定義的端口信息以及方法註釋,只保留服務啓動和中止的代碼。引入using SuperSocket.SocketEngine;使用BootStrap啓動ide
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; // } //} } }
最後咱們看一下修改後程序的運行結果:工具
斷開調試工具看一下效果,能夠看到服務端顯示客戶端斷開鏈接this
注意事項:spa
總結:
經過自定義Session和Server,能夠實現咱們本身的AppSession和AppServer容許你根據你業務的需求來方便的擴展SuperSocket,你能夠綁定session的鏈接和斷開事件,服務器實例的啓動和中止事件。你還能夠在AppServer的Setup方法中讀取你的自定義配置信息。總而言之,這些功能讓你方便的建立一個你所須要的socket服務器成爲可能。