perf[protocol]: 使用模板生成协议

This commit is contained in:
jaysunxiao
2022-05-16 23:00:41 +08:00
parent 5c379dd21c
commit bb1d7cccc4
24 changed files with 227 additions and 223 deletions
@@ -0,0 +1,74 @@
namespace CsProtocol.Buffer
{
public class BigEndianByteBuffer : ByteBuffer
{
// fast int to byte[] conversion and vice versa
// -> test with 100k conversions:
// BitConverter.GetBytes(ushort): 144ms
// bit shifting: 11ms
// -> 10x speed improvement makes this optimization actually worth it
// -> this way we don't need to allocate BinaryWriter/Reader either
// -> 4 bytes because some people may want to send messages larger than
// 64K bytes
// => big endian is standard for network transmissions, and necessary
// for compatibility with erlang
public static byte[] IntToBytesBigEndian(int value)
{
return new byte[]
{
(byte) (value >> 24),
(byte) (value >> 16),
(byte) (value >> 8),
(byte) value
};
}
public static int BytesToIntBigEndian(byte[] bytes)
{
return (bytes[0] << 24) |
(bytes[1] << 16) |
(bytes[2] << 8) |
bytes[3];
}
public override void WriteShort(short value)
{
WriteBytes(GetBytes(value));
}
public override short ReadShort()
{
return GetInt16(ReadBytes(2));
}
public override void WriteRawInt(int value)
{
WriteBytes(IntToBytesBigEndian(value));
}
public override int ReadRawInt()
{
return BytesToIntBigEndian(ReadBytes(4));
}
public override void WriteFloat(float value)
{
WriteBytes(GetBytes(value));
}
public override float ReadFloat()
{
return GetSingle(ReadBytes(4));
}
public override void WriteDouble(double value)
{
WriteBytes(GetBytes(value));
}
public override double ReadDouble()
{
return GetDouble(ReadBytes(8));
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,56 @@
using System;
namespace CsProtocol.Buffer
{
public class LittleEndianByteBuffer : ByteBuffer
{
/**
* 翻转字节数组,如果本地字节序列为低字节序列,则进行翻转以转换为高字节序列
*/
private static byte[] reverse(byte[] bytes)
{
Array.Reverse(bytes);
return bytes;
}
public override void WriteShort(short value)
{
WriteBytes(reverse(GetBytes(value)));
}
public override short ReadShort()
{
return GetInt16(reverse(ReadBytes(2)));
}
public override void WriteRawInt(int value)
{
WriteBytes(reverse(GetBytes(value)));
}
public override int ReadRawInt()
{
return GetInt32(reverse(ReadBytes(4)));
}
public override void WriteFloat(float value)
{
WriteBytes(reverse(GetBytes(value)));
}
public override float ReadFloat()
{
return GetSingle(reverse(ReadBytes(4)));
}
public override void WriteDouble(double value)
{
WriteBytes(reverse(GetBytes(value)));
}
public override double ReadDouble()
{
return GetDouble(reverse(ReadBytes(8)));
}
}
}
@@ -0,0 +1,7 @@
namespace CsProtocol.Buffer
{
public interface IPacket
{
short ProtocolId();
}
}
@@ -0,0 +1,12 @@
namespace CsProtocol.Buffer
{
public interface IProtocolRegistration
{
short ProtocolId();
void Write(ByteBuffer buffer, IPacket packet);
IPacket Read(ByteBuffer buffer);
}
}
@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using CsProtocol.Buffer;
namespace CsProtocol
{
public class ProtocolManager
{
public static readonly short MAX_PROTOCOL_NUM = short.MaxValue;
private static readonly IProtocolRegistration[] protocolList = new IProtocolRegistration[MAX_PROTOCOL_NUM];
public static void InitProtocol()
{
var protocolRegistrationTypeList = new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (assembly.Equals(typeof(ProtocolManager).Assembly))
{
var results = new List<Type>();
results.AddRange(assembly.GetTypes());
foreach (var type in results)
{
if (type.IsClass && !type.IsAbstract && typeof(IProtocolRegistration).IsAssignableFrom(type))
{
protocolRegistrationTypeList.Add(type);
}
}
}
}
foreach (var protocolRegistrationType in protocolRegistrationTypeList)
{
var protocolRegistration = (IProtocolRegistration) Activator.CreateInstance(protocolRegistrationType);
protocolList[protocolRegistration.ProtocolId()] = protocolRegistration;
}
}
public static IProtocolRegistration GetProtocol(short protocolId)
{
var protocol = protocolList[protocolId];
if (protocol == null)
{
throw new Exception("[protocolId:" + protocolId + "]协议不存在");
}
return protocol;
}
public static void Write(ByteBuffer buffer, IPacket packet)
{
var protocolId = packet.ProtocolId();
// 写入协议号
buffer.WriteShort(protocolId);
// 写入包体
GetProtocol(protocolId).Write(buffer, packet);
}
public static IPacket Read(ByteBuffer buffer)
{
var protocolId = buffer.ReadShort();
return GetProtocol(protocolId).Read(buffer);
}
}
}
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using CsProtocol.Buffer;
namespace CsProtocol
{
{}
public class {} : IPacket
{
{}
public static {} ValueOf({})
{
var packet = new {}();
{}
return packet;
}
public short ProtocolId()
{
return {};
}
}
public class {}Registration : IProtocolRegistration
{
public short ProtocolId()
{
return {};
}
public void Write(ByteBuffer buffer, IPacket packet)
{
if (buffer.WritePacketFlag(packet))
{
return;
}
{} message = ({}) packet;
{}
}
public IPacket Read(ByteBuffer buffer)
{
if (!buffer.ReadBool())
{
return null;
}
{} packet = new {}();
{}
return packet;
}
}
}