日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BeetleX之TCP消息通讯Protobuf/TLS

發布時間:2023/12/4 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BeetleX之TCP消息通讯Protobuf/TLS 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????????在網絡通訊應用中直接操作數據流是比較繁瑣的事情,畢竟在業務層面處理的都是對象化消息;為了讓網絡數據操作變得更友好直觀,一般都會引用序列化組件來處理網絡流和對象之前的轉換工作;在這里介紹組件如何使能Protobuf進行數據交互通訊。

協議定義

????????組件使用對象處理就不同之前HelloWorld示例一樣簡單操作流就可以,在這里需要進一步封裝一個簡單的應用協議。

|-----------------------------------------------------------------| |0?1?2?3?4?5?6?7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 | |----------------------------------------------------------------| |Probobuf數據流長度,占4字節 ?????????????????????????????????????| |----------------------------------------------------------------| |Protobuf數據流 | |----------------------------------------------------------------|

以上是一個簡單的應用協議,消息頭4字節描述消息的長度,對應長度的數據則是Protobuf序列化對象數據。但這樣的協議用在Protobuf上還是有問題,那就是無法知道這些數據對應于那個數據類型對象;所以還需要調整一下

|----------------------------------------------------------------| |0?1?2?3?4?5?6?7|0?1?2?3?4?5?6?7|0?1?2?3?4?5?6?7|0?1?2?3?4?5?6?7?| |----------------------------------------------------------------| |?Probobuf數據流長度,占4字節?????????????????????????????????????| |----------------------------------------------------------------| |?消息類型,占4字節???????????????????????????????????????????????| |----------------------------------------------------------------| |?Protobuf數據流?????????????????????????????????????????????????| |----------------------------------------------------------------|

在序列化數據流前添加了4字節用于描述對應的消息類型,對于這個類型其實可以使用2字節來描述,畢竟一個無符號的短整型可以描述6萬多個消息類型了。如果想表達得更友好些可以用字符來描述消息類型,只是字符所占有的空間比較多些。

協議分析器

????組件提供了FixedHeaderPacket抽象協議分析器來處理這種簡單應用協議,只要繼承重寫兩個方法即可完成。

public class ProtobufPacket : FixedHeaderPacket{static ProtobufPacket(){TypeHeaer.Register(typeof(ProtobufPacket).Assembly);}public static CustomTypeHeader TypeHeaer { get; private set; } = new CustomTypeHeader(MessageIDType.INT);public override IPacket Clone(){return new ProtobufPacket();}protected override object OnRead(ISession session, PipeStream stream){Type type = TypeHeaer.ReadType(stream);return ProtoBuf.Meta.RuntimeTypeModel.Default.Deserialize(type, stream, null, null, CurrentSize - 4);}protected override void OnWrite(ISession session, object data, PipeStream stream){TypeHeaer.WriteType(data, stream);ProtoBuf.Meta.RuntimeTypeModel.Default.Serialize(stream, data);}}

分析器定義CustomTypeHeader用于管理消息類型和數據的轉換,并在協議分析器靜態初始化的時候把當前程序集中所有消息映射關系加載進去。

  • 消息編碼

?????? OnWrite方法負責消息編碼,寫入消息類型,然后再寫入Protobuf序列化后的數據流。

  • 消息解碼

????? ?OnRead方法負責消息解碼, 先讀取消息類型,然后再拿數據流中的數據反序列化到相應的對象。正常做法這里需要判斷沒有獲取到正常的消息類型,沒有則拋對應的異常。

????????通過以上簡單的擴展,一個基于Protobuf的通訊應用協議就擴展完成。

定義消息

????? ?在這個示例中使用了Protobuf.net組件,用這組件在定義消息的時候還是要遵循某些規則的,接下來看一下消息的定義:

[MessageType(1)][ProtoContract]public class Register{[ProtoMember(1)]public string Name { get; set; }[ProtoMember(2)]public string EMail { get; set; }[ProtoMember(3)]public string Password { get; set; }}[MessageType(2)][ProtoContract]public class RegisterResult{[ProtoMember(1)]public bool Success { get; set; }[ProtoMember(2)]public string Message { get; set; }}

使用Protobuf.net組件需要用ProtoContract來描述一個序列化消息,并用ProtoMember來描述對應的成員屬性。MessageType特性用于描述消息類型對應關系。

制定服務

????????針對有協議解釋對象的TCP服務在處理上和基礎的hello world服務差不多,只是重寫接管的消息處理方法有所不同。

class Program : ServerHandlerBase {static IServer mServer;static void Main(string[] args){mServer = SocketFactory.CreateTcpServer(new Program(), new ProtobufPacket());mServer.Options.LogLevel?=?LogType.Info;???????//mServer.Options.DefaultListen.Port=9090//mServer.Options.DefaultListen.SSL = true;//mServer.Options.DefaultListen.CertificateFile = "ssl.pfx";//mServer.Options.DefaultListen.CertificatePassword = "123456";mServer.Open();System.Threading.Thread.Sleep(-1);}protected override void OnReceiveMessage(IServer server, ISession session, object message){RegisterResult result = new RegisterResult();if (message is Register register){server.Log(LogType.Info, session, $"{session.RemoteEndPoint} 注冊 {register.Name}");result.Success = true;result.Message = $"{register.Name}你已注冊成功,注冊郵件地址:{register.EMail}";}else{result.Success = false;result.Message = "非法請求";}session.Send(result);base.OnReceiveMessage(server, session, message);} }

通過重寫OnReceiveMessage方法來接管消息處理,在SSL處理上和之前的hello world示例是一樣的配置方式。

客戶端訪問

????????組件提供了AwaiterClient對象來實現基于async/await的消息接收處理,所以在這個示例中就沒有使用AsyncTcpClient這個類來處理了(AsyncTcpClient是基于事件方式接收消息在處理上相對麻煩一些)。

class Program {static async Task Main(string[] args){var client = new AwaiterClient("localhost", 9090, new ProtobufClientPacket());while (true){Register register = new Register();Console.Write("Enter you name:");register.Name = Console.ReadLine();Console.Write("Enter you email:");register.EMail = Console.ReadLine();Console.Write("Enter you password:");register.Password = Console.ReadLine();var result = await client.ReceiveFrom<RegisterResult>(register);Console.WriteLine($"{result.Success} {result.Message}");Console.WriteLine("-".PadLeft(100, '-'));}} }

以上代碼是向服務端發送一個注冊信息并等待返回輸出;通過AwaiterClient的ReciveFrom<T>方法可以在發送消息后等待一個消息返回;以下示例是運行顯示效果。

小結

????? ?雖然傳遞消息比起直接數據流操作方便很多,但如果針對每個邏輯都寫請求和響應其工作也是相當繁瑣的。組件有專門針對接口遠程調用擴展組件

https://github.com/IKende/XRPC

下載

鏈接:https://pan.baidu.com/s/118Qal6kJKZ6T9tglaZT3bw

提取碼:1b84

【BeetleX通訊框架代碼詳解】 BeetleX

開源跨平臺通訊框架(支持TLS)
輕松實現高性能:tcp、http、websocket、redis、rpc和網關等服務應用

https://beetlex.io

總結

以上是生活随笔為你收集整理的BeetleX之TCP消息通讯Protobuf/TLS的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。