SuperSocket封装成C#类库
将SuperSocket封装成类库之后可以将其集成进各种类型的应用,而不仅仅局限于控制台应用程序了,从而应用于不同的场景。这里以TelnetServer为例说明如何进行操作。
首先,创建一个C#类库项目LibSocketServer,添加SuperSocket引用(SuperSocket.Common.dll,SuperSocket.SocketBase.dll,SuperSocket.SocketEngine.dll),添加默认的日志框架log4net.dll引用。将log4net.config拷贝到项目文件夹的“Config”文件夹,然后设置它的“生成操作”为“内容”,设置它的“复制到输出目录”为“如果较新则复制”。
其次,添加SuperSocket完整的TelnetServer服务相关类,Socket服务管理类SocketServerManager。其中SocketServerManager对Bootstrap的设置是SuperSocket封装为类库的关键。
TelnetSession.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | using System; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Protocol; namespace LibSocketServer.Server { public class TelnetSession : AppSession<TelnetSession> { protected override void OnSessionStarted() { Console.WriteLine($ "New Session Connected: {RemoteEndPoint.Address} " + $ "@ {RemoteEndPoint.Port}." ); Send( "Welcome to SuperSocket Telnet Server." ); } protected override void HandleUnknownRequest(StringRequestInfo requestInfo) { Console.WriteLine($ "Unknown request {requestInfo.Key}." ); Send( "Unknown request." ); } protected override void HandleException(Exception e) { Console.WriteLine($ "Application error: {e.Message}." ); Send($ "Application error: {e.Message}." ); } protected override void OnSessionClosed(CloseReason reason) { Console.WriteLine($ "Session {RemoteEndPoint.Address} @ {RemoteEndPoint.Port} " + $ "Closed: {reason}." ); base .OnSessionClosed(reason); } } } |
TelnetServer.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | using System; using SuperSocket.SocketBase; using SuperSocket.SocketBase.Config; namespace LibSocketServer.Server { public class TelnetServer : AppServer<TelnetSession> { protected override bool Setup(IRootConfig rootConfig, IServerConfig config) { Console.WriteLine( "TelnetServer Setup" ); return base .Setup(rootConfig, config); } protected override void OnStarted() { Console.WriteLine( "TelnetServer OnStarted" ); base .OnStarted(); } protected override void OnStopped() { Console.WriteLine(); Console.WriteLine( "TelnetServer OnStopped" ); base .OnStopped(); } } } |
AddCommand.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; using System.Linq; using LibSocketServer.Server; using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; namespace LibSocketServer.Command { public class AddCommand : CommandBase<TelnetSession, StringRequestInfo> { public override string Name => "ADD" ; public override void ExecuteCommand(TelnetSession session, StringRequestInfo requestInfo) { Console.WriteLine($ "{Name} command: {requestInfo.Body}." ); session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString()); } } } |
EchoCommand.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | using System; using LibSocketServer.Server; using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; namespace LibSocketServer.Command { public class EchoCommand : CommandBase<TelnetSession, StringRequestInfo> { public override string Name => "ECHO" ; public override void ExecuteCommand(TelnetSession session, StringRequestInfo requestInfo) { Console.WriteLine($ "{Name} command: {requestInfo.Body}." ); session.Send(requestInfo.Body); } } } |
SocketServerManager.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | using System; using System.Reflection; using SuperSocket.SocketBase; using SuperSocket.SocketEngine; namespace LibSocketServer { public class SocketServerManager { private readonly IBootstrap _bootstrap; public bool Startup( int port) { if (!_bootstrap.Initialize()) { Console.WriteLine( "SuperSocket Failed to initialize!" ); return false ; } var ret = _bootstrap.Start(); Console.WriteLine($ "SuperSocket Start result: {ret}." ); return ret == StartResult.Success; } public void Shutdown() { _bootstrap.Stop(); } #region Singleton private static SocketServerManager _instance; private static readonly object LockHelper = new object (); private SocketServerManager() { var location = Assembly.GetExecutingAssembly().Location; var configFile = $ "{location}.config" ; _bootstrap = BootstrapFactory.CreateBootstrapFromConfigFile(configFile); } public static SocketServerManager Instance { get { if (_instance != null ) { return _instance; } lock (LockHelper) { _instance = _instance ?? new SocketServerManager(); } return _instance; } } #endregion } } |
再次,添加配置文件App.config到类库中,并设置其配置参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <? xml version="1.0" encoding="utf-8" ?> < configuration > < configSections > < section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/> </ configSections > <!-- SuperSocket配置的根节点 --> < superSocket > <!-- 服务器实例 --> < servers > < server name="TelnetServer" serverTypeName="TelnetServerType" ip="Any" port="2021"></ server > </ servers > <!-- 服务器类型 --> < serverTypes > < add name="TelnetServerType" type="LibSocketServer.Server.TelnetServer, LibSocketServer" /> </ serverTypes > </ superSocket > </ configuration > |
最后,创建控制台项目TelnetServerSample,添加项目引用LibSocketServer,然后在Program类中使用SocketServerManager进行SuperSocket的调用。
Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | using System; using LibSocketServer; namespace TelnetServerSample { class Program { static void Main() { try { //启动SuperSocket if (!SocketServerManager.Instance.Startup(2021)) { Console.WriteLine( "Failed to start TelnetServer!" ); Console.ReadKey(); return ; } Console.WriteLine( "TelnetServer is listening on port 2021." ); Console.WriteLine(); Console.WriteLine( "Press key 'q' to stop it!" ); Console.WriteLine(); while (Console.ReadKey().KeyChar.ToString().ToUpper() != "Q" ) { Console.WriteLine(); } //关闭SuperSocket SocketServerManager.Instance.Shutdown(); } catch (Exception e) { Console.WriteLine( "Exception: {0}" , e.Message); } Console.WriteLine(); Console.WriteLine( "TelnetServer was stopped!" ); Console.WriteLine( "Press any key to exit..." ); Console.ReadKey(); } } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器