使用Peach简化Socket网络通讯协议开发

使用Peach简化Socket网络通讯协议开发

Peach是基于DotNetty的Socket网络通讯帮助类库,可以帮助开发者简化使用DotNetty,关于DotNetty可参考我之前的这篇文章。
Peach内置实现了一个基于文本协议的CommandLineProtocol,下面的实例以这个协议展开,最后以DotBPE中Amp协议来介绍下如何扩展自定义协议。

QuickStart 使用

要使用Peach编写网络程序,一般只需要三个步骤

实现协议传输消息IMessage

实现协议打包和解包逻辑IProtocol

实现ISocketService完成服务端逻辑编写

在快速开始的实例中,我们使用内置的CommandLineProtocol,所以省去了步骤1,2让我们开始吧!

1 服务端 1.1 实现MyService

可分别重写

OnConnected 有客户端连接上的事件

OnDisConnected 客户端断开连接时的事件

OnReceive 收到客户端消息的事件

OnException 发生异常时的事件,如异常断开

public class MyService : Peach.AbsSocketService<Peach.Messaging.CommandLineMessage> { private readonly ILogger<MyService> _logger; public MyService(ILogger<MyService> logger) { _logger = logger; } public override void OnConnected(ISocketContext<CommandLineMessage> context) { _logger.LogInformation("client connected from {0}", context.RemoteEndPoint); base.OnConnected(context); } public override void OnDisconnected(ISocketContext<CommandLineMessage> context) { _logger.LogInformation("client disconnected from {0}", context.RemoteEndPoint); base.OnDisconnected(context); } public override void OnException(ISocketContext<CommandLineMessage> context, Exception ex) { _logger.LogError(ex,"client from {0}, occ error {1}", context.RemoteEndPoint,ex.Message); base.OnException(context, ex); } public override void OnReceive(ISocketContext<CommandLineMessage> context, CommandLineMessage msg) { string replyMessage = string.Empty; string replyCmd = string.Empty; switch (msg.Command) { case "echo": replyMessage = msg.Parameters[0]; replyCmd = "echo"; break; case "init": replyMessage = "ok"; replyCmd = "init_reply"; break; default: replyMessage = "error unknow command"; break; } Task.Run(async () => { await context.SendAsync(new CommandLineMessage(replyCmd, replyMessage)); }); } } 2. 挂载服务

服务默认挂载在5566端口

static void Main(string[] args) { var builder = new HostBuilder() .ConfigureServices((context,services) => { //协议 services.AddSingleton<IProtocol<CommandLineMessage>, CommandLineProtocol>(); //挂载服务逻辑 services.AddSingleton<ISocketService<CommandLineMessage>, MyService>(); //添加挂载的宿主服务 services.AddTcpServer<CommandLineMessage>(); }) .ConfigureLogging( logger => { logger.AddConsole(); } ); builder.RunConsoleAsync().Wait(); } 2. 客户端 2.1 使用内置的TcpClient

监听接收消息和链接的消息,如下所示:

TcpClient<CommandLineMessage> client = new TcpClient<CommandLineMessage>(new CommandLineProtocol()); client.OnReceived += Client_OnReceived; client.OnConnected += Client_OnConnected; Task.Run(async () => { //连接服务器 var socketContext = await client.ConnectAsync(new IPEndPoint(Hey.IPUtility.GetLocalIntranetIP(), 5566)); //发送消息 var initCmd = new Hey.Messaging.CommandLineMessage("init"); await socketContext.SendAsync(initCmd); }).Wait();

可用的事件:

OnReceived 当收到服务端消息时

OnError 当通讯发生异常时

OnConnected 当连接上服务器时

OnDisconnected 当与服务端断开链接时

OnIdleState 链接闲置时触发,一般在此事件中发送心跳包

3. 自定义协议

Peach支持使用自定义协议,扩展协议需要自行实现两个接口:

3.1. IMessage 接口

实现类具体实现通讯消息的内容载体,只需实现如何获取消息长度的属性

public interface IMessage { int Length { get; } } 3.2. IProtocol 接口

实现类需要描述消息头信息和具体打包解包逻辑,头信息描述参见ProtocolMeta字段描述

/// <summary> /// 协议接口 /// </summary> /// <typeparam></typeparam> public interface IProtocol<TMessage> where TMessage : Messaging.IMessage { ProtocolMeta GetProtocolMeta(); TMessage Parse(Buffer.IBufferReader reader); void Pack(Buffer.IBufferWriter writer, TMessage message); } 3.3 Amp协议

为了更好让读者理解自定义协议的操作,这里以DotBPE中的Amp协议为例,来具体讲解一下,先来看下Amp协议的说明:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 1415 16171819 20 <length>-21 +------------+----------+---------+------+-------------+---------+---------+--------+------------+ | <ver/argc> | <length> | <seq> |<type>| <serviceId> | <msgId> | <code> | <codec>| <data> | +------------+----------+---------+------+-------------+---------+---------+--------+------------+

Amp协议固定包头上21个字节,说明如下:

ver/argc = 版本 固定填1

length = 为总包长

seq = 请求序列号

type = 消息类型

1 = Request 请求消息

2 = Response 响应消息

3 = Notify 通知消息

4 = OneWayRequest 调用不关心返回值

serId = serviceId 服务号

msgId = msgId 消息ID

code = 当 type = 0 (请求时)固定传0 ,其他即为响应码,如果响应码不为0 则认为请求失败,具体错误码再定义

codecType = 编码方式 0=默认 Protobuf 1=MessagePack 2=JSON

data = 实际的业务数据

3.3.1 AmpMessage实现

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspjpg.html