摘要:} protected override void OnReceiveMessage(IServer server, ISession session, object message) { Console.WriteLine(message)。組件同樣提供相應的客戶端類來訪問相關服務,不過在訪問服務的時候同樣需要定義一個協議解釋器。

BeetleX 的使用非常簡單,通過 Stream 的數據流模式可以讓你輕鬆處理網絡數據;在處理 SSL 加密通訊的時候組件的使用也是非常方便,只需要簡單的配置證書即可完成基於 SSL 的網絡安全通訊,接下來介紹一下通過組件快速構建一個安全可靠的網絡服務。

引用組件

組件的最新版本是 1.4.9.6 可以通過訪問 https://www.nuget.org/packages/BeetleX/ 獲取最新版本,或直接通過 Nuget 進行安全組件。

證書文件

構建 SSL 服務需要一個 pfx 的證書文件,可以通過相關命令創建,如果不想麻煩可以通過 vs 在項目中籤名中添加一個即可創建一個 pfx 文件作爲 SSL 服務的證書文件。

定義協議數據

任何網絡通訊都具有一個應用協議,主要作用是根據網絡的字節流信息還原成具體可以操作的數據信息對象。組件通過 IPacket 接口來定義一個協議解釋器

public interface IPacket : IDisposable
    {
        EventHandler<PacketDecodeCompletedEventArgs> Completed { get; set; }

        IPacket Clone();
        void Decode(ISession session, Stream stream);
        void Encode(object data, ISession session, Stream stream);
        byte[] Encode(object data, IServer server);
        ArraySegment<byte> Encode(object data, IServer server, byte[] buffer);
    }

這個接口主要用於描述協議編碼和解碼的工作,並提供一個委託來觸發消息解釋完成的回調。實現這個接口需要一些工作不過組件提供了一個基礎的協議封包類 FixedHeaderPacket ,主要用於解決頭大小描述的消息體;接下來定義一個簡單的 String 消息協議處理器

public class StringPacket : BeetleX.Packets.FixedHeaderPacket
    {
        public override IPacket Clone()
        {
            return new StringPacket();
        }
        protected override object OnRead(ISession session, PipeStream stream)
        {
            return stream.ReadString(CurrentSize);
        }
        protected override void OnWrite(ISession session, object data, PipeStream stream)
        {
            stream.Write((string)data);
        }
    }

通過重寫 OnReadOnWrite 兩個方法來處理封包和解包的工作。這個協議解釋器的具體協議格如下:  |payload size|payload|

構建服務

有了協議分析類接下來的工作就可以實現一個基於 String 傳遞的網絡服務

class Program : ServerHandlerBase
    {
        private static IServer server;
        public static void Main(string[] args)
        {
            server = SocketFactory.CreateTcpServer<Program,StringPacket>();
            server.Options.DefaultListen.SSL = true;
            server.Options.DefaultListen.CertificateFile = "test.pfx";
            server.Options.DefaultListen.CertificatePassword = "123456";
            server.Options.LogLevel = LogType.Info;
            server.Open();
            Console.Read();
        }
        protected override void OnReceiveMessage(IServer server, ISession session, object message)
        {
            Console.WriteLine(message);
            server.Send($"hello {message}", session);
        }
    }

可以通過 SocketFactory.CreateTcpServer 方法來構建一個 TCP 服務,方法需要帶上接受網絡處理事件的 IServerHandler 和一個協議解釋對象 IPacket .以上服務是重寫 OnReceiveMessage 方法接收請求的消息處理並返回; IServerHandler 除也可以定義接收消息外還提供其他方法實現用於監控連接的不同事件處理,詳細下如:

public interface IServerHandler
    {
        void Connected(IServer server, ConnectedEventArgs e);
        void Connecting(IServer server, ConnectingEventArgs e);
        void Disconnect(IServer server, SessionEventArgs e);
        void Error(IServer server, ServerErrorEventArgs e);
        void Log(IServer server, ServerLogEventArgs e);
        void SessionDetection(IServer server, SessionDetectionEventArgs e);
        void SessionPacketDecodeCompleted(IServer server, PacketDecodeCompletedEventArgs e);
        void SessionReceive(IServer server, SessionReceiveEventArgs e);
    }

SSL配置

在打開服務端可以通過 server.Options 來配置相應的 SSL ,主要配置如下:

server.Options.DefaultListen.SSL = true;
     server.Options.DefaultListen.CertificateFile = "test.pfx";
     server.Options.DefaultListen.CertificatePassword = "123456";

通過以上配置就可以啓用一個 SSL 服務,啓動服務後可以看到服務的詳細信息

客戶端訪問

組件同樣提供相應的客戶端類來訪問相關服務,不過在訪問服務的時候同樣需要定義一個協議解釋器

public class StringPacket : BeetleX.Packets.FixeHeaderClientPacket
    {
        public override IClientPacket Clone()
        {
            return new StringPacket();
        }

        protected override object OnRead(IClient client, PipeStream stream)
        {
            return stream.ReadString(CurrentSize);
        }

        protected override void OnWrite(object data, IClient client, PipeStream stream)
        {
            stream.Write((string)data);
        }
    }

定義協議解釋器後,就可以建一個訪問對象了; 組件提供幾個客戶端訪問類分別是: TcpClien 同步, AsyncTcpClient 異步和 AwaiterClient 支持 await 接下來通過 AwaiterClient 來訪問服務:

AwaiterClient client = new AwaiterClient("127.0.0.1", 9090, new StringPacket(), "test");
            client.CertificateValidationCallback = (s, e, c, p) => true;
            while (true)
            {
                Console.Write("Enter Name:");
                var line = Console.ReadLine();
                client.Send(line);
                var result = await client.Receive();
                Console.WriteLine($"{DateTime.Now} {result}");
            }

在使用 SSL 時很多時候可以因爲服務名導致無法通過驗證,所以可以通過定義 CertificateValidationCallback 返回 True 來忽略相關驗證.這樣一個基於 SSL 訪問的網絡程序就完成,最後可以通過服務端的日誌查看相關工作情況:

相關文章