Custome 프로토콜 정의
SuperSocket 예제를 보면 대부분 string 기반의 프로토콜을 사용하고 있으나 binary 기반의 프로토콜을 정의해서 사용할 수 있다.
Packet은 보통 messageId + size + body의 구조를 가진다.
BinaryRequestInfo 클래스와 FixedHeaderReceiveFilter 클래스를 재정의 한다.
// 헤더는 4 바이트 정수값으로 key, 그 다음 body byte[]의 크기를 가리키는 4 바이트 정수값
public class EFBinaryRequestInfo : BinaryRequestInfo
{
public int nKey;
{
get;
private set;
}
public EFBinaryRequestInfo(int nKey, byte[] body)
: base(null, body)
{
this.nKey = key;
}
}
class ReceiveFilter : FixedHeaderReceiveFilter<EFBinaryREquestInfo>
{
public ReceiveFilter()
: base(8)
{
}
protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
{
if (!BitConverter.IsLitterEndian)
{
Array.Reverse(header, offset + 4, 4);
}
var nBodySize = BitConverter.ToInt32(header, offset + 4);
return nBodySize;
}
protected override EFBinaryRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
{
if (!BitConverter.IsLitterEndian)
{
Array.Reverse(header.Array, 0, 4);
}
return new EFBinaryRequestInfo(BitConverter.ToInt32(header.Array, 0), bodyBuffer.CloneRange(offset, length));
}
}
패킷 핸들러 정의
public class PK_LOGIN
{
public string ID;
public string Password;
}
public class PK_CHAT
{
public string sender;
public string msg;
}
public enum PACKETID : int
{
REQ_DUMMY_CHAT = 1,
REQ_LOGIN = 11,
}
public class CommonHandler
{
public void RequestLogin(NetworkSession session, EFBinaryRequestInfo requestInfo)
{}
public void RequestDummyChat(NetworkSession session, EFBinaryRequestInfo requestinfo)
{
string jsonstring = System.Text.Encoding.GetEncoding("utf-8").GetString(requestInfo.Body);
var deserializedProduct = JsonConvert.DeserializeObject<PK_CHAT>(jsonstring);
session.Send(deserializedProduct.sender + ":" + deserializedProduct.msg);
}
}
var HandlerMap = new Dictionary<int, Action<NetworkSession, EFBinaryRequestInfo>>();
CommonHandler CommonHan = new CommonHandler();
public BoardSeverNet()
: base(new DefaultReceiveFilterFactory<ReceiveFilter, EFBinaryRequestInfo>())
{
NewSessionConnected += new SessionHandler<NetworkSession>(OnConnected);
SessionClosed += new SessionHandler<NetworkSession, CloseReason>(OnClosed);
NewRequestReceived += new RequestHandler<NetworkSession, EFBinaryREquestInfo>(RequestReceived);
}
public void RegistHandler()
{
HandlerMap.Add((int)PACKETID.REQ_LOGIN, CommonHan.RequestLogin);
HandlerMap.Add((int)PACKETID.REQ_DUMMY_CHAT, CommonHan.RequestDummyChat);
}
public void StartPacketThread()
{
IsRunningPacketThread = true;
PacketThread = new System.Threading.Thread(this.ProcessPacket);
PacketThread.Start();
}
public void ProcessPacket()
{
while(IsRunningPacketThread)
{
if (PacketQueue.TryDequeue(out var packet))
{
var PacketId = packet.reqInfo.nKey;
if (HandlerMap.ContainsKey(PacketId))
{
HandlerMap[PacketId].Invoke(packet.session, packet.reqInfo);
}
}
System.Threading.Thread.Sleep(1);
}
}
출처
'프로그래밍' 카테고리의 다른 글
이진수 덧셈을 해보자! (1) | 2024.02.06 |
---|---|
추상 자료형(Abstract Data Type, ADT)란 무엇인가? (0) | 2024.01.25 |
비주얼 스튜디오 코드로 UML 그리기 (0) | 2023.12.19 |
디자인 패턴이란? (1) | 2023.11.29 |
SOLID 디자인 원칙 - 의존성 역전 원칙 (2) | 2023.11.21 |
댓글