內置的常用協議實現模版
關鍵字: TerminatorReceiveFilter, CountSpliterReceiveFilter, FixedSizeReceiveFilter, BeginEndMarkReceiveFilter, FixedHeaderReceiveFilter
閱讀了前面一篇文檔之后, 你可能會覺得用 SuperSocket 來實現你的自定義協議并不簡單。 為了讓這件事變得更容易一些, SuperSocket 提供了一些通用的協議解析工具, 你可以用他們簡單而且快速的實現你自己的通信協議:
- TerminatorReceiveFilter?(SuperSocket.SocketBase.Protocol.TerminatorReceiveFilter, SuperSocket.SocketBase)
- CountSpliterReceiveFilter?(SuperSocket.Facility.Protocol.CountSpliterReceiveFilter, SuperSocket.Facility)
- FixedSizeReceiveFilter?(SuperSocket.Facility.Protocol.FixedSizeReceiveFilter, SuperSocket.Facility)
- BeginEndMarkReceiveFilter?(SuperSocket.Facility.Protocol.BeginEndMarkReceiveFilter, SuperSocket.Facility)
- FixedHeaderReceiveFilter?(SuperSocket.Facility.Protocol.FixedHeaderReceiveFilter, SuperSocket.Facility)
TerminatorReceiveFilter - 結束符協議
與命令行協議類似,一些協議用結束符來確定一個請求.
例如, 一個協議使用兩個字符 "##" 作為結束符, 于是你可以使用類 "TerminatorReceiveFilterFactory":
/// <summary>
/// TerminatorProtocolServer
/// Each request end with the terminator "##"
/// ECHO Your message##
/// </summary>
public class TerminatorProtocolServer : AppServer
{public TerminatorProtocolServer(): base(new TerminatorReceiveFilterFactory("##")){}
}
默認的請求類型是 StringRequestInfo, 你也可以創建自己的請求類型, 不過這樣需要你做一點額外的工作:
基于TerminatorReceiveFilter實現你的接收過濾器(ReceiveFilter):
public class YourReceiveFilter : TerminatorReceiveFilter<YourRequestInfo>
{//More code
}
實現你的接收過濾器工廠(ReceiveFilterFactory)用于創建接受過濾器實例:
public class YourReceiveFilterFactory : IReceiveFilterFactory<YourRequestInfo>
{//More code
}
然后在你的 AppServer 中使用這個接收過濾器工廠(ReceiveFilterFactory).
CountSpliterReceiveFilter - 固定數量分隔符協議
有些協議定義了像這樣格式的請求 "#part1#part2#part3#part4#part5#part6#part7#". 每個請求有7個由 '#' 分隔的部分. 這種協議的實現非常簡單:
/// <summary>
/// Your protocol likes like the format below:
/// #part1#part2#part3#part4#part5#part6#part7#
/// </summary>
public class CountSpliterAppServer : AppServer
{public CountSpliterAppServer(): base(new CountSpliterReceiveFilterFactory((byte)'#', 8)) // 7 parts but 8 separators{}
}
你也可以使用下面的類更深入的定制這種協議:
CountSpliterReceiveFilter<TRequestInfo>
CountSpliterReceiveFilterFactory<TReceiveFilter>
CountSpliterReceiveFilterFactory<TReceiveFilter, TRequestInfo>
FixedSizeReceiveFilter - 固定請求大小的協議
在這種協議之中, 所有請求的大小都是相同的。如果你的每個請求都是有9個字符組成的字符串,如"KILL BILL", 你應該做的事就是想如下代碼這樣實現一個接收過濾器(ReceiveFilter):
class MyReceiveFilter : FixedSizeReceiveFilter<StringRequestInfo>
{public MyReceiveFilter(): base(9) //傳入固定的請求大小{}protected override StringRequestInfo ProcessMatchedRequest(byte[] buffer, int offset, int length, bool toBeCopied){//TODO: 通過解析到的數據來構造請求實例,并返回}
}
然后在你的 AppServer 類中使用這個接受過濾器 (ReceiveFilter):
public class MyAppServer : AppServer
{public MyAppServer(): base(new DefaultReceiveFilterFactory<MyReceiveFilter, StringRequestInfo>()) //使用默認的接受過濾器工廠 (DefaultReceiveFilterFactory){}
}
BeginEndMarkReceiveFilter - 帶起止符的協議
在這類協議的每個請求之中 都有固定的開始和結束標記。例如, 我有個協議,它的所有消息都遵循這種格式 "!xxxxxxxxxxxxxx$"。因此,在這種情況下, "!" 是開始標記, "$" 是結束標記,于是你的接受過濾器可以定義成這樣:
class MyReceiveFilter : BeginEndMarkReceiveFilter<StringRequestInfo>
{//開始和結束標記也可以是兩個或兩個以上的字節private readonly static byte[] BeginMark = new byte[] { (byte)'!' };private readonly static byte[] EndMark = new byte[] { (byte)'$' };public MyReceiveFilter(): base(BeginMark, EndMark) //傳入開始標記和結束標記{}protected override StringRequestInfo ProcessMatchedRequest(byte[] readBuffer, int offset, int length){//TODO: 通過解析到的數據來構造請求實例,并返回}
}
然后在你的 AppServer 類中使用這個接受過濾器 (ReceiveFilter):
public class MyAppServer : AppServer
{public MyAppServer(): base(new DefaultReceiveFilterFactory<MyReceiveFilter, StringRequestInfo>()) //使用默認的接受過濾器工廠 (DefaultReceiveFilterFactory){}
}
FixedHeaderReceiveFilter - 頭部格式固定并且包含內容長度的協議
這種協議將一個請求定義為兩大部分, 第一部分定義了包含第二部分長度等等基礎信息. 我們通常稱第一部分為頭部.
例如, 我們有一個這樣的協議: 頭部包含 6 個字節, 前 4 個字節用于存儲請求的名字, 后兩個字節用于代表請求體的長度:
/// +-------+---+-------------------------------+
/// |request| l | |
/// | name | e | request body |
/// | (4) | n | |
/// | |(2)| |
/// +-------+---+-------------------------------+
使用 SuperSocket, 你可以非常方便的實現這種協議:
class MyReceiveFilter : FixedHeaderReceiveFilter<BinaryRequestInfo>
{public MyReceiveFilter(): base(6){}protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length){return (int)header[offset + 4] * 256 + (int)header[offset + 5];}protected override BinaryRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length){return new BinaryRequestInfo(Encoding.UTF8.GetString(header.Array, header.Offset, 4), bodyBuffer.CloneRange(offset, length));}
}
你需要基于類FixedHeaderReceiveFilter實現你自己的接收過濾器.
- 傳入父類構造函數的 6 表示頭部的長度;
- 方法"GetBodyLengthFromHeader(...)" 應該根據接收到的頭部返回請求體的長度;
- 方法 ResolveRequestInfo(....)" 應該根據你接收到的請求頭部和請求體返回你的請求類型的實例.
然后你就可以使用接收或者自己定義的接收過濾器工廠來在 SuperSocket 中啟用該協議.
- Prev: 內置的命令行協議
- Next: 使用 IRequestInfo 和 IReceiveFilter 等等其他對象來實現自定義協議
? 2018 - GetDocs.Net -?Hosted by BuyVM