网络客户端ISocketClient和网络会话ISocketSession都继承了ISocketRemoteISocketRemote表示远程通信,核心就是收发数据。
下面是ISocketRemote接口的主要实现
/// <summary>远程通信Socket,仅具有收发功能</summary> public interface ISocketRemote : ISocket { #region 属性 /// <summary>远程地址</summary> NetUri Remote { get; set; } /// <summary>通信开始时间</summary> DateTime StartTime { get; } /// <summary>最后一次通信时间,主要表示会话活跃时间,包括收发</summary> DateTime LastTime { get; } /// <summary>缓冲区大小</summary> Int32 BufferSize { get; set; } #endregion #region 发送 /// <summary>发送数据</summary> /// <remarks> /// 目标地址由<seealso cref="Remote"/>决定 /// </remarks> /// <param name="pk">数据包</param> /// <returns>是否成功</returns> Boolean Send(Packet pk); #endregion #region 接收 /// <summary>接收数据。阻塞当前线程等待返回</summary> /// <returns></returns> Packet Receive(); /// <summary>数据到达事件</summary> event EventHandler<ReceivedEventArgs> Received; /// <summary>消息到达事件</summary> event EventHandler<MessageEventArgs> MessageReceived; #endregion #region 数据包处理 /// <summary>粘包处理接口</summary> IPacket Packet { get; set; } /// <summary>异步发送数据并等待响应</summary> /// <param name="pk"></param> /// <returns></returns> Task<Packet> SendAsync(Packet pk); /// <summary>发送消息并等待响应</summary> /// <param name="msg"></param> /// <returns></returns> Task<IMessage> SendAsync(IMessage msg); #endregion }
应用级消息收发伪代码:
var str = "{action:Open,args:{index:3},remark:打开3号灯}"; var client = new NetUri("tcp://127.0.0.1:1234").CreateRemote(); client.Packet = new DefaultPacket(); var rs = await client.SendAsync(str.GetBytes()); // rs = "{result:true,data:3号灯已打开}"
上面的DefaultPacket正是 新生命团队标准网络封包协议
请求响应包的头部,都会增加4字节,Json字符串作为负载数据。
正是增加的这4字节,确保了请求响应的准确配对(序列号匹配),解决了粘包问题(头部长度)
即使没有默认封包DefualtPacket,上面代码也是可以工作的,只是这样就失去了准确配对和粘包拆分,要求业务层不能频繁收发。
End.