Skip to content

Commit

Permalink
为封包发送加入标志位
Browse files Browse the repository at this point in the history
  • Loading branch information
laolarou726 committed Aug 6, 2023
1 parent 81ef9f2 commit ed24726
Show file tree
Hide file tree
Showing 23 changed files with 275 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@
<RootNamespace>Hive.Framework.Codec.Abstractions</RootNamespace>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Hive.Common.Shared\Hive.Common.Shared.csproj" />
</ItemGroup>

</Project>
7 changes: 5 additions & 2 deletions Common/Hive.Common.Codec.Abstractions/IPacketCodec.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Hive.Framework.Shared;

namespace Hive.Framework.Codec.Abstractions
{
Expand All @@ -12,11 +13,13 @@ public interface IPacketCodec<TId> where TId : unmanaged

IPacketIdMapper<TId> PacketIdMapper { get; }

ReadOnlyMemory<byte> GetPacketIdMemory(ReadOnlyMemory<byte> payload);
TId GetPacketId(ReadOnlyMemory<byte> idMemory);

ReadOnlyMemory<byte> GetPacketIdMemory(ReadOnlyMemory<byte> payload);
ReadOnlyMemory<byte> GetPacketFlagsMemory(ReadOnlyMemory<byte> payload);
PacketFlags GetPacketFlags(ReadOnlyMemory<byte> data);

ReadOnlyMemory<byte> Encode<T>(T obj);
ReadOnlyMemory<byte> Encode<T>(T obj, PacketFlags flags);

PacketDecodeResultWithId<TId> Decode(ReadOnlySpan<byte> data);
}
Expand Down
20 changes: 17 additions & 3 deletions Common/Hive.Common.Codec.Abstractions/PacketDecodeResultWithId.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
namespace Hive.Framework.Codec.Abstractions
using Hive.Framework.Shared;

namespace Hive.Framework.Codec.Abstractions
{
public interface IPacketDecodeResult<out TPayload>
{
object?[] Prefixes { get; }
PacketFlags Flags { get; }
TPayload Payload { get; }
}

public readonly struct PacketDecodeResultWithId<TId> : IPacketDecodeResult<object> where TId : unmanaged
{
public object?[] Prefixes { get; }
public PacketFlags Flags { get; }
public object Payload { get; }
public TId PacketId { get; }

public PacketDecodeResultWithId(object?[] prefixes, TId packetId, object payload)
public PacketDecodeResultWithId(
object?[] prefixes,
PacketFlags flags,
TId packetId,
object payload)
{
Prefixes = prefixes;
Flags = flags;
PacketId = packetId;
Payload = payload;
}
Expand All @@ -23,11 +32,16 @@ public PacketDecodeResultWithId(object?[] prefixes, TId packetId, object payload
public readonly struct PacketDecodeResult<TPayload> : IPacketDecodeResult<TPayload>
{
public object?[] Prefixes { get; }
public PacketFlags Flags { get; }
public TPayload Payload { get; }

public PacketDecodeResult(object?[] prefixes, TPayload payload)
public PacketDecodeResult(
object?[] prefixes,
PacketFlags flags,
TPayload payload)
{
Prefixes = prefixes;
Flags = flags;
Payload = payload;
}
}
Expand Down
42 changes: 34 additions & 8 deletions Common/Hive.Common.Codec.Bson/BsonPacketCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
using System.Linq;
using Microsoft.Extensions.ObjectPool;
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Hive.Framework.Codec.Bson;

Expand Down Expand Up @@ -36,15 +36,31 @@ public ReadOnlyMemory<byte> GetPacketIdMemory(ReadOnlyMemory<byte> payload)
if (payload.IsEmpty)
throw new InvalidOperationException($"{nameof(payload)} has length of 0!");

return payload.Slice(2, 2);
return payload.Slice(6, 2);
}

public ushort GetPacketId(ReadOnlyMemory<byte> idMemory)
{
return BitConverter.ToUInt16(idMemory.Span);
}

public ReadOnlyMemory<byte> Encode<T>(T obj)
public ReadOnlyMemory<byte> GetPacketFlagsMemory(ReadOnlyMemory<byte> payload)
{
if (payload.IsEmpty)
throw new InvalidOperationException($"{nameof(payload)} has length of 0!");

return payload.Slice(2, 4);
}

public PacketFlags GetPacketFlags(ReadOnlyMemory<byte> data)
{
var flagsMemory = data.Slice(6, 4);
var flags = BitConverter.ToUInt32(flagsMemory.Span);

return (PacketFlags) flags;
}

public ReadOnlyMemory<byte> Encode<T>(T obj, PacketFlags flags)
{
var writer = WriterPool.Get();

Expand All @@ -58,12 +74,17 @@ public ReadOnlyMemory<byte> Encode<T>(T obj)
var packetId = PacketIdMapper.GetPacketId(typeof(T));

Span<byte> lengthHeader = stackalloc byte[2];
Span<byte> flagsHeader = stackalloc byte[4];
Span<byte> typeHeader = stackalloc byte[2];

// [LENGTH (2) | TYPE (2) | CONTENT]
BitConverter.TryWriteBytes(lengthHeader, (ushort)(dataSpan.Length + 2));
// [LENGTH (2) | PACKET_FLAGS (4) | TYPE (2) | CONTENT]
BitConverter.TryWriteBytes(lengthHeader, (ushort)(dataSpan.Length + 4 + 2));
writer.Write(lengthHeader);

// Packet Flags
BitConverter.TryWriteBytes(flagsHeader, (uint)flags);
writer.Write(flagsHeader);

// Packet Id
BitConverter.TryWriteBytes(typeHeader, packetId);
writer.Write(typeHeader);
Expand All @@ -88,12 +109,17 @@ public unsafe PacketDecodeResultWithId<ushort> Decode(ReadOnlySpan<byte> data)
// 负载长度
// var packetLengthSpan = data[..2];

// 封包标志
var packetFlagsSpan = data.Slice(2, 4);
var flagsUint = BitConverter.ToUInt32(packetFlagsSpan);
var flags = (PacketFlags)flagsUint;

// 封包类型
var packetIdSpan = data.Slice(2, 2);
var packetIdSpan = data.Slice(6, 2);
var packetId = BitConverter.ToUInt16(packetIdSpan);

// 封包前缀
var payloadStartIndex = 4;
var payloadStartIndex = 8;
var packetPrefixes = Array.Empty<object?>();

if (PrefixResolvers?.Any() ?? false)
Expand All @@ -116,7 +142,7 @@ public unsafe PacketDecodeResultWithId<ushort> Decode(ReadOnlySpan<byte> data)
var packetType = PacketIdMapper.GetPacketType(packetId);
var payload = BsonSerializer.Deserialize(dataMs, packetType);

return new PacketDecodeResultWithId<ushort>(packetPrefixes, packetId, payload);
return new PacketDecodeResultWithId<ushort>(packetPrefixes, flags, packetId, payload);
}
}
}
40 changes: 33 additions & 7 deletions Common/Hive.Common.Codec.MemoryPack/MemoryPackPacketCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,31 @@ public ReadOnlyMemory<byte> GetPacketIdMemory(ReadOnlyMemory<byte> payload)
if (payload.IsEmpty)
throw new InvalidOperationException($"{nameof(payload)} has length of 0!");

return payload.Slice(2, 2);
return payload.Slice(6, 2);
}

public ushort GetPacketId(ReadOnlyMemory<byte> idMemory)
{
return BitConverter.ToUInt16(idMemory.Span);
}

public ReadOnlyMemory<byte> Encode<T>(T obj)
public ReadOnlyMemory<byte> GetPacketFlagsMemory(ReadOnlyMemory<byte> payload)
{
if (payload.IsEmpty)
throw new InvalidOperationException($"{nameof(payload)} has length of 0!");

return payload.Slice(2, 4);
}

public PacketFlags GetPacketFlags(ReadOnlyMemory<byte> data)
{
var flagsMemory = data.Slice(2, 4);
var flags = BitConverter.ToUInt32(flagsMemory.Span);

return (PacketFlags)flags;
}

public ReadOnlyMemory<byte> Encode<T>(T obj, PacketFlags flags)
{
var writer = WriterPool.Get();

Expand All @@ -53,12 +69,17 @@ public ReadOnlyMemory<byte> Encode<T>(T obj)
var packetId = PacketIdMapper.GetPacketId(typeof(T));

Span<byte> lengthHeader = stackalloc byte[2];
Span<byte> flagsHeader = stackalloc byte[4];
Span<byte> typeHeader = stackalloc byte[2];

// Packet Length [LENGTH (2) | TYPE (2) | CONTENT]
BitConverter.TryWriteBytes(lengthHeader, (ushort)(objBytes.Length + 2));
// [LENGTH (2) | PACKET_FLAGS (4) | TYPE (2) | CONTENT]
BitConverter.TryWriteBytes(lengthHeader, (ushort)(objBytes.Length + 4 + 2));
writer.Write(lengthHeader);

// Packet Flags
BitConverter.TryWriteBytes(flagsHeader, (uint)flags);
writer.Write(flagsHeader);

// Packet Id
BitConverter.TryWriteBytes(typeHeader, packetId);
writer.Write(typeHeader);
Expand All @@ -84,12 +105,17 @@ public PacketDecodeResultWithId<ushort> Decode(ReadOnlySpan<byte> data)
// 负载长度
// var packetLengthSpan = data[..2];

// 封包标志
var packetFlagsSpan = data.Slice(2, 4);
var flagsUint = BitConverter.ToUInt32(packetFlagsSpan);
var flags = (PacketFlags)flagsUint;

// 封包类型
var packetIdSpan = data.Slice(2, 2);
var packetIdSpan = data.Slice(6, 2);
var packetId = BitConverter.ToUInt16(packetIdSpan);

// 封包前缀
var payloadStartIndex = 4;
var payloadStartIndex = 8;
var packetPrefixes = Array.Empty<object?>();

if (PrefixResolvers?.Any() ?? false)
Expand All @@ -108,6 +134,6 @@ public PacketDecodeResultWithId<ushort> Decode(ReadOnlySpan<byte> data)
var packetType = PacketIdMapper.GetPacketType(packetId);
var payload = MemoryPackSerializer.Deserialize(packetType, packetData);

return new PacketDecodeResultWithId<ushort>(packetPrefixes, packetId, payload);
return new PacketDecodeResultWithId<ushort>(packetPrefixes, flags, packetId, payload);
}
}
40 changes: 33 additions & 7 deletions Common/Hive.Common.Codec.Protobuf/ProtoBufPacketCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,31 @@ public ReadOnlyMemory<byte> GetPacketIdMemory(ReadOnlyMemory<byte> payload)
if (payload.IsEmpty)
throw new InvalidOperationException($"{nameof(payload)} has length of 0!");

return payload.Slice(2, 2);
return payload.Slice(6, 2);
}

public ushort GetPacketId(ReadOnlyMemory<byte> idMemory)
{
return BitConverter.ToUInt16(idMemory.Span);
}

public ReadOnlyMemory<byte> Encode<T>(T obj)
public ReadOnlyMemory<byte> GetPacketFlagsMemory(ReadOnlyMemory<byte> payload)
{
if (payload.IsEmpty)
throw new InvalidOperationException($"{nameof(payload)} has length of 0!");

return payload.Slice(2, 4);
}

public PacketFlags GetPacketFlags(ReadOnlyMemory<byte> data)
{
var flagsMemory = data.Slice(2, 4);
var flags = BitConverter.ToUInt32(flagsMemory.Span);

return (PacketFlags)flags;
}

public ReadOnlyMemory<byte> Encode<T>(T obj, PacketFlags flags)
{
var writer = WriterPool.Get();

Expand All @@ -56,12 +72,17 @@ public ReadOnlyMemory<byte> Encode<T>(T obj)
var packetId = PacketIdMapper.GetPacketId(typeof(T));

Span<byte> lengthHeader = stackalloc byte[2];
Span<byte> flagsHeader = stackalloc byte[4];
Span<byte> typeHeader = stackalloc byte[2];

// Packet Length [LENGTH (2) | TYPE (2) | CONTENT]
BitConverter.TryWriteBytes(lengthHeader, (ushort)(contentMeasure.Length + 2));
// [LENGTH (2) | PACKET_FLAGS (4) | TYPE (2) | CONTENT]
BitConverter.TryWriteBytes(lengthHeader, (ushort)(contentMeasure.Length + 4 + 2));
writer.Write(lengthHeader);

// Packet Flags
BitConverter.TryWriteBytes(flagsHeader, (uint)flags);
writer.Write(flagsHeader);

// Packet Id
BitConverter.TryWriteBytes(typeHeader, packetId);
writer.Write(typeHeader);
Expand All @@ -86,12 +107,17 @@ public PacketDecodeResultWithId<ushort> Decode(ReadOnlySpan<byte> data)
// 负载长度
// var packetLengthSpan = data[..2];

// 封包标志
var packetFlagsSpan = data.Slice(2, 4);
var flagsUint = BitConverter.ToUInt32(packetFlagsSpan);
var flags = (PacketFlags)flagsUint;

// 封包类型
var packetIdSpan = data.Slice(2, 2);
var packetIdSpan = data.Slice(6, 2);
var packetId = BitConverter.ToUInt16(packetIdSpan);

// 封包前缀
var payloadStartIndex = 4;
var payloadStartIndex = 8;
var packetPrefixes = Array.Empty<object?>();

if (PrefixResolvers?.Any() ?? false)
Expand All @@ -110,6 +136,6 @@ public PacketDecodeResultWithId<ushort> Decode(ReadOnlySpan<byte> data)
var packetType = PacketIdMapper.GetPacketType(packetId);
var payload = RuntimeTypeModel.Default.Deserialize(packetType, packetData);

return new PacketDecodeResultWithId<ushort>(packetPrefixes, packetId, payload);
return new PacketDecodeResultWithId<ushort>(packetPrefixes, flags, packetId, payload);
}
}
3 changes: 2 additions & 1 deletion Common/Hive.Common.Networking.Abstractions/ISender.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Hive.Framework.Shared;

namespace Hive.Framework.Networking.Abstractions
{
Expand All @@ -8,6 +9,6 @@ namespace Hive.Framework.Networking.Abstractions
/// <typeparam name="TId">封包 ID 类型(通常为 ushort)</typeparam>
public interface ISender<TId>
{
ValueTask SendAsync<T>(T obj);
ValueTask SendAsync<T>(T obj, PacketFlags flags);
}
}
7 changes: 6 additions & 1 deletion Common/Hive.Common.Networking.Abstractions/ISession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ public interface ISession<TSender> : IShouldDestroySession where TSender : ISess

ValueTask DoConnect();
ValueTask DoDisconnect();
ValueTask Send(ReadOnlyMemory<byte> data);
/// <summary>
/// 将原始数据流加入发送队列
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
ValueTask SendAsync(ReadOnlyMemory<byte> data);
ValueTask SendOnce(ReadOnlyMemory<byte> data);
ValueTask<int> ReceiveOnce(Memory<byte> buffer);

Expand Down
2 changes: 1 addition & 1 deletion Common/Hive.Common.Networking.Kcp/KcpSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ private async Task UpdateLoop()
}
}

public override async ValueTask Send(ReadOnlyMemory<byte> data)
public override async ValueTask SendAsync(ReadOnlyMemory<byte> data)
{
if (CancellationTokenSource == null)
throw new ArgumentNullException(nameof(CancellationTokenSource));
Expand Down
Loading

0 comments on commit ed24726

Please sign in to comment.