From 12a522460732b8f6e8cf7a87c514b64f611525f6 Mon Sep 17 00:00:00 2001 From: laolarou Date: Mon, 7 Aug 2023 21:15:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BD=91=E5=85=B3=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E8=AE=BE=E7=BD=AE=E3=80=81=E4=BC=98=E5=8C=96=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=AB=AF=E5=B0=81=E5=8C=85=E8=BD=AC=E5=8F=91=E7=AD=96?= =?UTF-8?q?=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Hive.Common.Codec.Bson/BsonPacketCodec.cs | 2 +- .../IClientManager.cs | 9 ++++ .../IServerReplyPacket.cs | 9 ---- .../AbstractClientManager.cs | 3 ++ .../AbstractGatewayServer.cs | 47 ++++++++++++++----- .../AbstractSession.cs | 7 +-- .../Helpers/SessionExtensions.cs | 1 + .../Hive.Common.Networking.Tcp/TcpSession.cs | 2 +- .../Kcp/FakeKcpClientManager.cs | 16 +++++-- .../BasicNetworking/Kcp/KcpBsonTests.cs | 2 +- .../BasicNetworking/Kcp/KcpMemoryPackTests.cs | 2 +- .../BasicNetworking/Kcp/KcpProtobufTests.cs | 2 +- .../Quic/FakeQuicClientManager.cs | 14 +++++- .../BasicNetworking/Quic/QuicBsonTests.cs | 2 +- .../Quic/QuicMemoryPackTests.cs | 2 +- .../BasicNetworking/Quic/QuicProtobufTests.cs | 2 +- .../Tcp/FakeTcpClientManager.cs | 11 +++++ .../BasicNetworking/Tcp/TcpBsonTests.cs | 2 +- .../BasicNetworking/Tcp/TcpMemoryPackTests.cs | 2 +- .../BasicNetworking/Tcp/TcpProtobufTests.cs | 2 +- .../Udp/FakeUdpClientManager.cs | 13 ++++- .../BasicNetworking/Udp/UdpBsonTests.cs | 2 +- .../BasicNetworking/Udp/UdpMemoryPackTests.cs | 2 +- .../BasicNetworking/Udp/UdpProtobufTests.cs | 2 +- .../GatewayServer/Tcp/FakeTcpGatewayServer.cs | 28 +++++------ .../Tcp/TcpGateWayServerTests.cs | 32 +++++++------ .../Messages/DefaultServerReplyPacket.cs | 16 ------- .../Messages/ServerReplyTestMessage1.cs | 12 ----- .../Helpers/BufferWriterExtensions.cs | 13 +++++ .../{ => Helpers}/MemoryHelper.cs | 2 +- .../{ => Helpers}/NetworkHelper.cs | 4 +- Common/Hive.Common.Shared/PacketFlags.cs | 28 +++++++++-- 32 files changed, 186 insertions(+), 107 deletions(-) delete mode 100644 Common/Hive.Common.Networking.Abstractions/IServerReplyPacket.cs delete mode 100644 Common/Hive.Common.Networking.Tests/Messages/DefaultServerReplyPacket.cs delete mode 100644 Common/Hive.Common.Networking.Tests/Messages/ServerReplyTestMessage1.cs create mode 100644 Common/Hive.Common.Shared/Helpers/BufferWriterExtensions.cs rename Common/Hive.Common.Shared/{ => Helpers}/MemoryHelper.cs (90%) rename Common/Hive.Common.Shared/{ => Helpers}/NetworkHelper.cs (93%) diff --git a/Common/Hive.Common.Codec.Bson/BsonPacketCodec.cs b/Common/Hive.Common.Codec.Bson/BsonPacketCodec.cs index 52178fe..19c2655 100644 --- a/Common/Hive.Common.Codec.Bson/BsonPacketCodec.cs +++ b/Common/Hive.Common.Codec.Bson/BsonPacketCodec.cs @@ -54,7 +54,7 @@ public ReadOnlyMemory GetPacketFlagsMemory(ReadOnlyMemory payload) public PacketFlags GetPacketFlags(ReadOnlyMemory data) { - var flagsMemory = data.Slice(6, 4); + var flagsMemory = data.Slice(2, 4); var flags = BitConverter.ToUInt32(flagsMemory.Span); return (PacketFlags) flags; diff --git a/Common/Hive.Common.Networking.Abstractions/IClientManager.cs b/Common/Hive.Common.Networking.Abstractions/IClientManager.cs index 9d70586..ae85d86 100644 --- a/Common/Hive.Common.Networking.Abstractions/IClientManager.cs +++ b/Common/Hive.Common.Networking.Abstractions/IClientManager.cs @@ -8,6 +8,8 @@ public interface IClientManager where TSession : ISession where TSessionId : unmanaged { + int SessionIdSize { get; } + /// /// 根据会话获取编码后的 C2S(Client -> Server) 前缀 /// 这个方法通常被用于在网关服务器向具体服务器转发时注入的额外信息 @@ -16,6 +18,13 @@ public interface IClientManager /// 编码后的会话前缀 ReadOnlyMemory GetEncodedC2SSessionPrefix(TSession session); + /// + /// 从完整的封包中提取并解析会话 ID + /// + /// + /// + TSessionId ResolveSessionPrefix(ReadOnlyMemory payload); + /// /// 根据会话获取会话 ID /// diff --git a/Common/Hive.Common.Networking.Abstractions/IServerReplyPacket.cs b/Common/Hive.Common.Networking.Abstractions/IServerReplyPacket.cs deleted file mode 100644 index 8df2d82..0000000 --- a/Common/Hive.Common.Networking.Abstractions/IServerReplyPacket.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Hive.Framework.Networking.Abstractions; - -public interface IServerReplyPacket where TId : unmanaged -{ - TId SendTo { get; } - ReadOnlyMemory InnerPayload { get; } -} \ No newline at end of file diff --git a/Common/Hive.Common.Networking.Shared/AbstractClientManager.cs b/Common/Hive.Common.Networking.Shared/AbstractClientManager.cs index c6e54d5..9b8ed53 100644 --- a/Common/Hive.Common.Networking.Shared/AbstractClientManager.cs +++ b/Common/Hive.Common.Networking.Shared/AbstractClientManager.cs @@ -29,6 +29,8 @@ public abstract class AbstractClientManager : IClientManag private bool _isClientLinkHolderRunning; + public abstract int SessionIdSize { get; } + public event EventHandler>? OnClientConnected; public event EventHandler>? OnClientDisconnected; @@ -91,6 +93,7 @@ public virtual void StopClientConnectionHolder() } public abstract ReadOnlyMemory GetEncodedC2SSessionPrefix(TSession session); + public abstract TSessionId ResolveSessionPrefix(ReadOnlyMemory payload); protected abstract void RegisterHeartBeatMessage(TSession session); protected abstract void RegisterSigninMessage(TSession session); diff --git a/Common/Hive.Common.Networking.Shared/AbstractGatewayServer.cs b/Common/Hive.Common.Networking.Shared/AbstractGatewayServer.cs index bb5827b..0331cdc 100644 --- a/Common/Hive.Common.Networking.Shared/AbstractGatewayServer.cs +++ b/Common/Hive.Common.Networking.Shared/AbstractGatewayServer.cs @@ -5,6 +5,7 @@ using Hive.Framework.Networking.Abstractions; using Hive.Framework.Networking.Abstractions.EventArgs; using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Shared; @@ -79,7 +80,7 @@ protected virtual void AddPacketRoute(TId packetId, TSession session) /// 客户端只应该在接受到该方法发送的消息后才开始进行数据传输,否则可能会导致前半部分数据丢失 /// /// - protected abstract void NotifyClientCanStartTransmitMessage(TSession session); + protected abstract ValueTask NotifyClientCanStartTransmitMessage(TSession session); /// /// 服务器注册方法 @@ -90,14 +91,6 @@ protected virtual void AddPacketRoute(TId packetId, TSession session) /// protected abstract void RegisterServerRegistrationMessage(TSession session); - /// - /// 服务器回复数据包注册方法 - /// 一般情况下,此方法需要注册相应的数据包来帮助网关服务器向正确的客户端传输数据。 - /// 服务端回复数据包需实现 ,其中包括目标客户端 ID 以及数据包负载。 - /// - /// - protected abstract void RegisterServerReplyMessage(TSession session); - /// /// 客户端数据包传送起始注册方法 /// 一般情况下,此方法需要在接受到相应的起始数据包后开始转发该客户端会话发送的所有请求,通过调用 来将数据包转发给对应服务器 @@ -127,6 +120,7 @@ protected virtual void InvokeOnClientConnected(object sender, ClientConnectionCh /// /// 客户端数据转发方法 /// 一般情况下,此方法会拆解客户端数据包,并向其追加客户端会话 ID 等信息,并将数据包转发给相应服务器 + /// 注意:在调用该转发方法时,应始终保持 [封包 ID] 的下一位为 [客户端会话 ID],并且服务端也应该从 [客户端会话 ID] 部分开始解析自定义包头 /// /// /// @@ -157,12 +151,41 @@ protected virtual async ValueTask DoForwardDataToServerAsync(TSession session, R await serverSession!.SendAsync(repackedData); } - protected virtual async ValueTask DoForwardDataToClientAsync(IServerReplyPacket packet) + /// + /// 服务端数据转发方法 + /// 一般情况下,此方法会拆解服务端数据包,并解析其中包含的客户端会话 ID 等信息,并将数据包转发给相应客户端 + /// 注意:在调用该转发方法时,应始终保持 [封包 ID] 的下一位为 [客户端会话 ID],并且服务端也应该从 [客户端会话 ID] 部分开始解析自定义包头 + /// + /// + /// + /// + protected virtual async ValueTask DoForwardDataToClientAsync(ReadOnlyMemory data) { - if (!Acceptor.ClientManager.TryGetSession(packet.SendTo, out var session)) + var packetIdMemory = PacketCodec.GetPacketIdMemory(data); + var packetFlags = PacketCodec.GetPacketFlags(data); + + if (!packetFlags.HasFlag(PacketFlags.S2CPacket)) return; + + var sessionId = Acceptor.ClientManager.ResolveSessionPrefix(data); + + if (!Acceptor.ClientManager.TryGetSession(sessionId, out var session)) return; - await session!.SendAsync(packet.InnerPayload); + var newFlag = packetFlags | PacketFlags.Finalized; + var packetFlagsMemory = BitConverter.GetBytes((uint) newFlag); + var payload = data[(2 + 4 + packetIdMemory.Length + Acceptor.ClientManager.SessionIdSize)..]; + var resultLength = packetFlagsMemory.Length + packetIdMemory.Length + payload.Length; + var lengthMemory = BitConverter.GetBytes((ushort)resultLength).AsMemory(); + + // [LENGTH (2) | PACKET_FLAGS (4) | PACKET_ID | SESSION_ID | PAYLOAD] + var repackedData = + MemoryHelper.CombineMemory( + lengthMemory, + packetFlagsMemory, + packetIdMemory, + payload); + + await session!.SendAsync(repackedData); } protected virtual bool GetServerSession(TId packetId, bool useLoadBalancer, out TSession? serverSession) diff --git a/Common/Hive.Common.Networking.Shared/AbstractSession.cs b/Common/Hive.Common.Networking.Shared/AbstractSession.cs index 4492038..224c8bc 100644 --- a/Common/Hive.Common.Networking.Shared/AbstractSession.cs +++ b/Common/Hive.Common.Networking.Shared/AbstractSession.cs @@ -164,9 +164,10 @@ protected async ValueTask ProcessPacket(ReadOnlyMemory payloadBytes) var packetFlags = PacketCodec.GetPacketFlags(payloadBytes); var id = PacketCodec.GetPacketId(idMemory); - if (RedirectReceivedData && - (RedirectPacketIds?.Contains(id) ?? false) && - !packetFlags.HasFlag(PacketFlags.ServerReply)) + var isPacketFinalized = packetFlags.HasFlag(PacketFlags.Finalized); + var shouldRedirect = RedirectReceivedData && (RedirectPacketIds?.Contains(id) ?? false); + + if ((shouldRedirect || packetFlags.HasFlag(PacketFlags.S2CPacket)) && !isPacketFinalized) { await InvokeDataReceivedEventAsync(idMemory, payloadBytes.ToArray().AsMemory()); diff --git a/Common/Hive.Common.Networking.Shared/Helpers/SessionExtensions.cs b/Common/Hive.Common.Networking.Shared/Helpers/SessionExtensions.cs index b0c5f05..8817e9c 100644 --- a/Common/Hive.Common.Networking.Shared/Helpers/SessionExtensions.cs +++ b/Common/Hive.Common.Networking.Shared/Helpers/SessionExtensions.cs @@ -4,6 +4,7 @@ using Hive.Framework.Codec.Abstractions; using Hive.Framework.Networking.Abstractions; using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Shared.Helpers; diff --git a/Common/Hive.Common.Networking.Tcp/TcpSession.cs b/Common/Hive.Common.Networking.Tcp/TcpSession.cs index e6c8be1..f9b2140 100644 --- a/Common/Hive.Common.Networking.Tcp/TcpSession.cs +++ b/Common/Hive.Common.Networking.Tcp/TcpSession.cs @@ -47,7 +47,7 @@ public TcpSession(string addressWithPort, IPacketCodec packetCodec, IDataDi protected override async ValueTask DispatchPacket(IPacketDecodeResult? packet, Type? packetType = null) { if (packet == null) return; - + await DataDispatcher.DispatchAsync(this, packet, packetType); } diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/FakeKcpClientManager.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/FakeKcpClientManager.cs index 3e5fee1..7652d19 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/FakeKcpClientManager.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/FakeKcpClientManager.cs @@ -3,7 +3,6 @@ using Hive.Framework.Networking.Tests.Messages; using Hive.Framework.Networking.Tests.Messages.BidirectionalPacket; using Hive.Framework.Shared; -using System.Text; namespace Hive.Framework.Networking.Tests.BasicNetworking.Kcp; @@ -18,7 +17,9 @@ protected override void RegisterHeartBeatMessage(KcpSession session) UpdateHeartBeatReceiveTime(sessionId); }); } - + + public override int SessionIdSize => 16; + public int ConnectedClient { get; private set; } public int SigninMessageVal { get; private set; } public int SignOutMessageVal { get; private set; } @@ -30,7 +31,16 @@ protected override void RegisterHeartBeatMessage(KcpSession session) public override ReadOnlyMemory GetEncodedC2SSessionPrefix(KcpSession session) { - return Encoding.ASCII.GetBytes(GetSessionId(session).ToString("N")); + return GetSessionId(session).ToByteArray(); + } + + public override Guid ResolveSessionPrefix(ReadOnlyMemory payload) + { + // [LENGTH (2) | PACKET_FLAGS (4) | PACKET_ID | SESSION_ID | PAYLOAD] + const int startIndex = 2 + 4 + sizeof(ushort); + var sessionIdMemory = payload.Slice(startIndex, 16); + + return new Guid(sessionIdMemory.Span); } protected override void InvokeOnClientDisconnected(Guid sessionId, KcpSession session, bool isClientRequest) diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpBsonTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpBsonTests.cs index 34a23be..b6ad976 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpBsonTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpBsonTests.cs @@ -1,9 +1,9 @@ using Hive.Framework.Codec.Bson; using Hive.Framework.Networking.Kcp; using Hive.Framework.Networking.Shared; -using Hive.Framework.Shared; using System.Net; using Hive.Common.Codec.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Tests.BasicNetworking.Kcp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpMemoryPackTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpMemoryPackTests.cs index 0ed26f3..7a0bc50 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpMemoryPackTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpMemoryPackTests.cs @@ -1,9 +1,9 @@ using Hive.Framework.Networking.Kcp; using Hive.Framework.Networking.Shared; -using Hive.Framework.Shared; using System.Net; using Hive.Common.Codec.MemoryPack; using Hive.Common.Codec.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Tests.BasicNetworking.Kcp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpProtobufTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpProtobufTests.cs index 1d9b65a..50ed143 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpProtobufTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Kcp/KcpProtobufTests.cs @@ -2,7 +2,7 @@ using Hive.Framework.Codec.Protobuf; using Hive.Framework.Networking.Kcp; using Hive.Framework.Networking.Shared; -using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; using System.Net; namespace Hive.Framework.Networking.Tests.BasicNetworking.Kcp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/FakeQuicClientManager.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/FakeQuicClientManager.cs index ba852f1..c66b264 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/FakeQuicClientManager.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/FakeQuicClientManager.cs @@ -1,5 +1,6 @@ using System.Runtime.Versioning; using System.Text; +using Hive.Framework.Networking.Kcp; using Hive.Framework.Networking.Quic; using Hive.Framework.Networking.Shared; using Hive.Framework.Networking.Tests.Messages; @@ -21,6 +22,8 @@ protected override void RegisterHeartBeatMessage(QuicSession session) }); } + public override int SessionIdSize => 16; + public int ConnectedClient { get; private set; } public int SigninMessageVal { get; private set; } public int SignOutMessageVal { get; private set; } @@ -32,7 +35,16 @@ protected override void RegisterHeartBeatMessage(QuicSession session) public override ReadOnlyMemory GetEncodedC2SSessionPrefix(QuicSession session) { - return Encoding.ASCII.GetBytes(GetSessionId(session).ToString("N")); + return GetSessionId(session).ToByteArray(); + } + + public override Guid ResolveSessionPrefix(ReadOnlyMemory payload) + { + // [LENGTH (2) | PACKET_FLAGS (4) | PACKET_ID | SESSION_ID | PAYLOAD] + const int startIndex = 2 + 4 + sizeof(ushort); + var sessionIdMemory = payload.Slice(startIndex, 16); + + return new Guid(sessionIdMemory.Span); } protected override void InvokeOnClientDisconnected(Guid sessionId, QuicSession session, bool isClientRequest) diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicBsonTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicBsonTests.cs index 25e2382..d43eab2 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicBsonTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicBsonTests.cs @@ -3,8 +3,8 @@ using Hive.Framework.Networking.Shared; using System.Net; using System.Runtime.Versioning; -using Hive.Framework.Shared; using Hive.Common.Codec.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Tests.BasicNetworking.Quic; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicMemoryPackTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicMemoryPackTests.cs index 25267cc..e68162b 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicMemoryPackTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicMemoryPackTests.cs @@ -1,10 +1,10 @@ using Hive.Framework.Networking.Quic; using Hive.Framework.Networking.Shared; -using Hive.Framework.Shared; using System.Net; using System.Runtime.Versioning; using Hive.Common.Codec.MemoryPack; using Hive.Common.Codec.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Tests.BasicNetworking.Quic; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicProtobufTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicProtobufTests.cs index a51db8a..b48df09 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicProtobufTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Quic/QuicProtobufTests.cs @@ -2,7 +2,7 @@ using Hive.Framework.Codec.Protobuf; using Hive.Framework.Networking.Quic; using Hive.Framework.Networking.Shared; -using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; using System.Net; using System.Runtime.Versioning; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/FakeTcpClientManager.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/FakeTcpClientManager.cs index 493a3c8..b2c2289 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/FakeTcpClientManager.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/FakeTcpClientManager.cs @@ -18,6 +18,8 @@ protected override void RegisterHeartBeatMessage(TcpSession session) }); } + public override int SessionIdSize => 16; + public int ConnectedClient { get; private set; } public int SigninMessageVal { get; private set; } public int SignOutMessageVal { get; private set; } @@ -32,6 +34,15 @@ public override ReadOnlyMemory GetEncodedC2SSessionPrefix(TcpSession payload) + { + // [LENGTH (2) | PACKET_FLAGS (4) | PACKET_ID | SESSION_ID | PAYLOAD] + const int startIndex = 2 + 4 + sizeof(ushort); + var sessionIdMemory = payload.Slice(startIndex, 16); + + return new Guid(sessionIdMemory.Span); + } + protected override void InvokeOnClientDisconnected(Guid sessionId, TcpSession session, bool isClientRequest) { base.InvokeOnClientDisconnected(sessionId, session, isClientRequest); diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpBsonTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpBsonTests.cs index 3d1d882..a0b7c7d 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpBsonTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpBsonTests.cs @@ -2,7 +2,7 @@ using Hive.Framework.Codec.Bson; using Hive.Framework.Networking.Shared; using Hive.Framework.Networking.Tcp; -using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; using System.Net; namespace Hive.Framework.Networking.Tests.BasicNetworking.Tcp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpMemoryPackTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpMemoryPackTests.cs index de30fe7..c6277da 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpMemoryPackTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpMemoryPackTests.cs @@ -1,9 +1,9 @@ using Hive.Framework.Networking.Shared; using Hive.Framework.Networking.Tcp; -using Hive.Framework.Shared; using System.Net; using Hive.Common.Codec.MemoryPack; using Hive.Common.Codec.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Tests.BasicNetworking.Tcp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpProtobufTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpProtobufTests.cs index fdbfac1..21c6251 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpProtobufTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Tcp/TcpProtobufTests.cs @@ -2,7 +2,7 @@ using Hive.Framework.Codec.Protobuf; using Hive.Framework.Networking.Shared; using Hive.Framework.Networking.Tcp; -using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; using System.Net; namespace Hive.Framework.Networking.Tests.BasicNetworking.Tcp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/FakeUdpClientManager.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/FakeUdpClientManager.cs index d60f517..9c93d23 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/FakeUdpClientManager.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/FakeUdpClientManager.cs @@ -19,6 +19,8 @@ protected override void RegisterHeartBeatMessage(UdpSession session) }); } + public override int SessionIdSize => 16; + public int ConnectedClient { get; private set; } public int SigninMessageVal { get; private set; } public int SignOutMessageVal { get; private set; } @@ -30,7 +32,16 @@ protected override void RegisterHeartBeatMessage(UdpSession session) public override ReadOnlyMemory GetEncodedC2SSessionPrefix(UdpSession session) { - return Encoding.ASCII.GetBytes(GetSessionId(session).ToString("N")); + return GetSessionId(session).ToByteArray(); + } + + public override Guid ResolveSessionPrefix(ReadOnlyMemory payload) + { + // [LENGTH (2) | PACKET_FLAGS (4) | PACKET_ID | SESSION_ID | PAYLOAD] + const int startIndex = 2 + 4 + sizeof(ushort); + var sessionIdMemory = payload.Slice(startIndex, 16); + + return new Guid(sessionIdMemory.Span); } protected override void InvokeOnClientDisconnected(Guid sessionId, UdpSession session, bool isClientRequest) diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpBsonTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpBsonTests.cs index 2e7b60a..354fc3b 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpBsonTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpBsonTests.cs @@ -2,7 +2,7 @@ using Hive.Framework.Codec.Bson; using Hive.Framework.Networking.Shared; using Hive.Framework.Networking.Udp; -using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; using System.Net; namespace Hive.Framework.Networking.Tests.BasicNetworking.Udp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpMemoryPackTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpMemoryPackTests.cs index 88a7c2a..8839ce8 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpMemoryPackTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpMemoryPackTests.cs @@ -1,9 +1,9 @@ using Hive.Framework.Networking.Shared; using Hive.Framework.Networking.Udp; -using Hive.Framework.Shared; using System.Net; using Hive.Common.Codec.MemoryPack; using Hive.Common.Codec.Shared; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Tests.BasicNetworking.Udp; diff --git a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpProtobufTests.cs b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpProtobufTests.cs index 1217f59..bdd1b7d 100644 --- a/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpProtobufTests.cs +++ b/Common/Hive.Common.Networking.Tests/BasicNetworking/Udp/UdpProtobufTests.cs @@ -2,7 +2,7 @@ using Hive.Framework.Codec.Protobuf; using Hive.Framework.Networking.Shared; using Hive.Framework.Networking.Udp; -using Hive.Framework.Shared; +using Hive.Framework.Shared.Helpers; using System.Net; namespace Hive.Framework.Networking.Tests.BasicNetworking.Udp; diff --git a/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/FakeTcpGatewayServer.cs b/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/FakeTcpGatewayServer.cs index ab55dfe..9ee0d70 100644 --- a/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/FakeTcpGatewayServer.cs +++ b/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/FakeTcpGatewayServer.cs @@ -21,43 +21,43 @@ public FakeTcpGatewayServer( protected override void RegisterServerRegistrationMessage(TcpSession session) { - session.OnReceive((message, tcpSession) => + session.OnReceive(async (message, tcpSession) => { + tcpSession.OnDataReceived += TcpServerSessionOnOnDataReceived; + foreach (var packetId in message.Payload.PackagesToReceive) { AddPacketRoute(packetId, tcpSession); - RegisterServerReplyMessage(tcpSession); RegisteredForwardPacketCount++; } - }); - } - protected override void RegisterServerReplyMessage(TcpSession session) - { - session.OnReceive(async (message, _) => - { - await DoForwardDataToClientAsync(message.Payload); + await NotifyClientCanStartTransmitMessage(tcpSession); }); } - protected override async void NotifyClientCanStartTransmitMessage(TcpSession session) + protected override async ValueTask NotifyClientCanStartTransmitMessage(TcpSession session) { await session.SendAsync(new ClientCanTransmitMessage(), PacketFlags.None); } protected override void RegisterClientStartTransmitMessage(TcpSession session) { - session.OnReceive((message, tcpSession) => + session.OnReceive(async (message, tcpSession) => { tcpSession.RedirectPacketIds = message.Payload.RedirectPacketIds.ToHashSet(); - tcpSession.OnDataReceived += TcpSessionOnOnDataReceived; + tcpSession.OnDataReceived += TcpClientSessionOnOnDataReceived; tcpSession.RedirectReceivedData = true; - NotifyClientCanStartTransmitMessage(session); + await NotifyClientCanStartTransmitMessage(tcpSession); }); } - private async Task TcpSessionOnOnDataReceived(object? sender, ReceivedDataEventArgs e) + private async Task TcpServerSessionOnOnDataReceived(object? sender, ReceivedDataEventArgs e) + { + await DoForwardDataToClientAsync(e.Data); + } + + private async Task TcpClientSessionOnOnDataReceived(object? sender, ReceivedDataEventArgs e) { await DoForwardDataToServerAsync((TcpSession)sender!, e.Data); } diff --git a/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/TcpGateWayServerTests.cs b/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/TcpGateWayServerTests.cs index 67ca844..019c663 100644 --- a/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/TcpGateWayServerTests.cs +++ b/Common/Hive.Common.Networking.Tests/GatewayServer/Tcp/TcpGateWayServerTests.cs @@ -1,9 +1,11 @@ -using System.Net; +using System.Buffers; +using System.Net; using Hive.Common.Codec.Shared; using Hive.Framework.Codec.Abstractions; using Hive.Framework.Codec.Protobuf; using Hive.Framework.Networking.Abstractions; using Hive.Framework.Networking.Shared; +using Hive.Framework.Networking.Shared.Helpers; using Hive.Framework.Networking.Shared.LoadBalancers; using Hive.Framework.Networking.Tcp; using Hive.Framework.Networking.Tests.BasicNetworking; @@ -11,6 +13,7 @@ using Hive.Framework.Networking.Tests.Messages; using Hive.Framework.Shared; using Hive.Framework.Shared.Collections; +using Hive.Framework.Shared.Helpers; namespace Hive.Framework.Networking.Tests.GatewayServer.Tcp; @@ -91,8 +94,6 @@ public void Setup() _packetIdMapper.Register(); _packetIdMapper.Register(); _packetIdMapper.Register(); - _packetIdMapper.Register(); - _packetIdMapper.Register(); _clientPacketCodec = new ProtoBufPacketCodec(_packetIdMapper); _serverPacketCodec = new ProtoBufPacketCodec(_packetIdMapper, new IPacketPrefixResolver[] @@ -265,7 +266,11 @@ public async Task RandomizedMessageSendTest() _server.OnReceive((message1, _) => { - testStrList.Add(message1.Payload.Content!); + var str = message1.Payload.Content!; + + if (str is "123" or "pp") return; + + testStrList.Add(str); }); await Task.Delay(100); @@ -296,17 +301,14 @@ public async Task ClientMessageReceiveTest() { packetReceived++; - var innerPayload = - session.PacketCodec.Encode( - new ServerRedirectTestMessage2 { Value = message.Payload.Value }, - PacketFlags.ServerReply); - - await session.SendAsync( - new DefaultServerReplyPacket + await session.SendWithPrefix( + _serverPacketCodec, + PacketFlags.S2CPacket, + new ServerRedirectTestMessage2 { Value = message.Payload.Value }, + writer => { - SendTo = (Guid)message.Prefixes[0]!, - InnerPayload = innerPayload - }, PacketFlags.None); + writer.WriteGuid((Guid)message.Prefixes[0]!); + }); }); var client1Counter = 0L; @@ -338,7 +340,7 @@ await session.SendAsync( for (var i = 0; i < packetSendCount; i++) { var flag = Random.Shared.Next(0, 2) == 1; - var rnd = Random.Shared.Next(); + var rnd = Random.Shared.Next(-100, 100); var client = flag ? _client1 : _client2; if (flag) diff --git a/Common/Hive.Common.Networking.Tests/Messages/DefaultServerReplyPacket.cs b/Common/Hive.Common.Networking.Tests/Messages/DefaultServerReplyPacket.cs deleted file mode 100644 index a4df003..0000000 --- a/Common/Hive.Common.Networking.Tests/Messages/DefaultServerReplyPacket.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Hive.Framework.Networking.Abstractions; -using MemoryPack; -using ProtoBuf; - -namespace Hive.Framework.Networking.Tests.Messages; - -[ProtoContract] -[MemoryPackable] -public partial class DefaultServerReplyPacket : IServerReplyPacket -{ - [ProtoMember(1)] - public Guid SendTo { get; set; } - - [ProtoMember(2)] - public ReadOnlyMemory InnerPayload { get; set; } -} \ No newline at end of file diff --git a/Common/Hive.Common.Networking.Tests/Messages/ServerReplyTestMessage1.cs b/Common/Hive.Common.Networking.Tests/Messages/ServerReplyTestMessage1.cs deleted file mode 100644 index 0d8ddf7..0000000 --- a/Common/Hive.Common.Networking.Tests/Messages/ServerReplyTestMessage1.cs +++ /dev/null @@ -1,12 +0,0 @@ -using MemoryPack; -using ProtoBuf; - -namespace Hive.Framework.Networking.Tests.Messages; - -[ProtoContract] -[MemoryPackable] -public partial class ServerReplyTestMessage1 -{ - [ProtoMember(1)] - public string? Content { get; set; } -} \ No newline at end of file diff --git a/Common/Hive.Common.Shared/Helpers/BufferWriterExtensions.cs b/Common/Hive.Common.Shared/Helpers/BufferWriterExtensions.cs new file mode 100644 index 0000000..d2c6c57 --- /dev/null +++ b/Common/Hive.Common.Shared/Helpers/BufferWriterExtensions.cs @@ -0,0 +1,13 @@ +using System; +using System.Buffers; + +namespace Hive.Framework.Shared.Helpers +{ + public static class BufferWriterExtensions + { + public static void WriteGuid(this IBufferWriter writer, Guid val) + { + writer.Write(val.ToByteArray()); + } + } +} \ No newline at end of file diff --git a/Common/Hive.Common.Shared/MemoryHelper.cs b/Common/Hive.Common.Shared/Helpers/MemoryHelper.cs similarity index 90% rename from Common/Hive.Common.Shared/MemoryHelper.cs rename to Common/Hive.Common.Shared/Helpers/MemoryHelper.cs index 6273b33..025c975 100644 --- a/Common/Hive.Common.Shared/MemoryHelper.cs +++ b/Common/Hive.Common.Shared/Helpers/MemoryHelper.cs @@ -1,7 +1,7 @@ using System; using System.Buffers; -namespace Hive.Framework.Shared +namespace Hive.Framework.Shared.Helpers { public static class MemoryHelper { diff --git a/Common/Hive.Common.Shared/NetworkHelper.cs b/Common/Hive.Common.Shared/Helpers/NetworkHelper.cs similarity index 93% rename from Common/Hive.Common.Shared/NetworkHelper.cs rename to Common/Hive.Common.Shared/Helpers/NetworkHelper.cs index 868a230..a3016ee 100644 --- a/Common/Hive.Common.Shared/NetworkHelper.cs +++ b/Common/Hive.Common.Shared/Helpers/NetworkHelper.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.Linq; -namespace Hive.Framework.Shared +namespace Hive.Framework.Shared.Helpers { public static class NetworkHelper { - private static readonly Random Random = new Random((int)DateTime.Now.Ticks); + private static readonly Random Random = new ((int)DateTime.Now.Ticks); /// /// 获取操作系统已用的端口号 diff --git a/Common/Hive.Common.Shared/PacketFlags.cs b/Common/Hive.Common.Shared/PacketFlags.cs index bd533f9..f1964fb 100644 --- a/Common/Hive.Common.Shared/PacketFlags.cs +++ b/Common/Hive.Common.Shared/PacketFlags.cs @@ -1,10 +1,22 @@ -namespace Hive.Framework.Shared +using System; + +namespace Hive.Framework.Shared { + [Flags] public enum PacketFlags : uint { None = 0, + + /// + /// 指示封包在分发时应广播给所有会话 + /// Broadcast = 1 << 0, - ServerReply = 1 << 1, + + /// + /// 指示封包已经经过最终处理,这种类型的数据包将不再被允许被重新转发、拆分和重打包 + /// + Finalized = 1 << 1, + RESERVED_1 = 1 << 2, RESERVED_2 = 1 << 3, RESERVED_3 = 1 << 4, @@ -14,8 +26,16 @@ public enum PacketFlags : uint RESERVED_7 = 1 << 8, RESERVED_8 = 1 << 9, RESERVED_9 = 1 << 10, - RESERVED_10 = 1 << 11, - RESERVED_11 = 1 << 12, + + /// + /// 指示封包的发送方向为 C(Client) -> S(Server),该封包应严格遵循发送方向 + /// + C2SPacket = 1 << 11, + /// + /// 指示封包的发送方向为 S(Server) -> C(Client),该封包应严格遵循发送方向 + /// + S2CPacket = 1 << 12, + RESERVED_12 = 1 << 13, RESERVED_13 = 1 << 14, RESERVED_14 = 1 << 15,