SuperSocket封裝成C#類(lèi)庫(kù)的步驟
將SuperSocket封裝成類(lèi)庫(kù)之后可以將其集成進(jìn)各種類(lèi)型的應(yīng)用,而不僅僅局限于控制臺(tái)應(yīng)用程序了,從而應(yīng)用于不同的場(chǎng)景。這里以TelnetServer為例說(shuō)明如何進(jìn)行操作。
首先,創(chuàng)建一個(gè)C#類(lèi)庫(kù)項(xiàng)目LibSocketServer
添加SuperSocket引用(SuperSocket.Common.dll,SuperSocket.SocketBase.dll,SuperSocket.SocketEngine.dll),添加默認(rèn)的日志框架log4net.dll引用。將log4net.config拷貝到項(xiàng)目文件夾的“Config”文件夾,然后設(shè)置它的“生成操作”為“內(nèi)容”,設(shè)置它的“復(fù)制到輸出目錄”為“如果較新則復(fù)制”。
其次,添加SuperSocket完整的TelnetServer服務(wù)相關(guān)類(lèi),Socket服務(wù)管理類(lèi)SocketServerManager。
其中SocketServerManager對(duì)Bootstrap的設(shè)置是SuperSocket封裝為類(lèi)庫(kù)的關(guān)鍵。
TelnetSession.cs
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
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
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
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
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到類(lèi)庫(kù)中,并設(shè)置其配置參數(shù)。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/> </configSections> <!-- SuperSocket配置的根節(jié)點(diǎn) --> <superSocket> <!-- 服務(wù)器實(shí)例 --> <servers> <server name="TelnetServer" serverTypeName="TelnetServerType" ip="Any" port="2021"></server> </servers> <!-- 服務(wù)器類(lèi)型 --> <serverTypes> <add name="TelnetServerType" type="LibSocketServer.Server.TelnetServer, LibSocketServer" /> </serverTypes> </superSocket> </configuration>
最后,創(chuàng)建控制臺(tái)項(xiàng)目TelnetServerSample,添加項(xiàng)目引用LibSocketServer,然后在Program類(lèi)中使用SocketServerManager進(jìn)行SuperSocket的調(diào)用。
Program.cs
using System;
using LibSocketServer;
namespace TelnetServerSample
{
class Program
{
static void Main()
{
try
{
//啟動(dòng)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();
}
//關(guān)閉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();
}
}
}
以上就是SuperSocket封裝成C#類(lèi)庫(kù)的步驟的詳細(xì)內(nèi)容,更多關(guān)于SuperSocket封裝成C#類(lèi)庫(kù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#五類(lèi)運(yùn)算符使用表達(dá)式樹(shù)進(jìn)行操作
這篇文章介紹了C#五類(lèi)運(yùn)算符使用表達(dá)式樹(shù)進(jìn)行操作,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01
C#使用JavaScriptSerializer序列化時(shí)的時(shí)間類(lèi)型處理
這篇文章主要為大家詳細(xì)介紹了C#使用JavaScriptSerializer序列化時(shí)的時(shí)間類(lèi)型處理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
C#三種判斷數(shù)據(jù)庫(kù)中取出的字段值是否為空(NULL) 的方法
最近操作數(shù)據(jù)庫(kù),需要判斷返回的字段值是否為空,在網(wǎng)上收集了3種方法供大家參考2013-04-04
淺析C# 使用Process調(diào)用外部程序中所遇到的參數(shù)問(wèn)題
這篇文章主要介紹了C# 使用Process調(diào)用外部程序中所遇到的參數(shù)問(wèn)題,需要的朋友可以參考下2017-03-03
C#面向?qū)ο笤O(shè)計(jì)原則之組合/聚合復(fù)用原則
這篇文章介紹了C#面向?qū)ο笤O(shè)計(jì)原則之組合/聚合復(fù)用原則,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
C#如何通過(guò)匿名類(lèi)直接使用訪問(wèn)JSON數(shù)據(jù)詳解
這篇文章主要給大家介紹了關(guān)于C#如何通過(guò)匿名類(lèi)直接使用訪問(wèn)JSON數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧。2018-02-02
C#如何將DataTable導(dǎo)出到Excel解決方案
由于公司項(xiàng)目中需要將系統(tǒng)內(nèi)用戶操作的所有日志進(jìn)行轉(zhuǎn)存?zhèn)浞?,考慮到以后可能還需要還原,所以最后決定將日志數(shù)據(jù)備份到Excel中2012-11-11

