1. 程式人生 > 程式設計 >SuperSocket封裝成C#類庫的步驟

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

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到類庫中,並設定其配置引數。

<?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

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();
}
}
}

GitHub Sample

以上就是SuperSocket封裝成C#類庫的步驟的詳細內容,更多關於SuperSocket封裝成C#類庫的資料請關注我們其它相關文章!