supersocket實際應用之你畫我猜遊戲(一)
阿新 • • 發佈:2022-04-09
supersocket這款元件,讓不懂tcp/ip的人都能開發出網路應用。我們不必在開發與自己主要應用不相關的程式碼了,主要精力都能放在設計業務邏輯上面了。 現在使用現成又完備的元件,真是大大的提高了開發效率。我主要使用的是1.6.5版本的supersocket,用於編寫.net framework下的wpf和winform應用。我正在進行的你畫我猜玩具專案也只是作為週末的消磨時間的一種方式。另外寫winform寫多了,寫wpf都還像在寫winform一樣,不過wpf的ui還是具有更強的展示能力。
supersocket v1.6原始碼地址:https://github.com/kerryjiang/SuperSocket/tree/v1.6
作者部落格:https://home.cnblogs.com/u/jzywh/
在用nuget引用supersocket時,注意元件之間的依賴關係,不然會在使用時出現某個依賴項找不到的問題。因為supersocket引用的元件的簽名和自己專案引用的元件的簽名不一樣造成的。這也是.net為了防止元件被替換為不安全的元件所採取的方式。但這也讓許多開發者都有一段頭疼的經歷。
服務端引用的元件有:
我為了除錯,就引用的是原始碼中的專案了。
客戶端的引用:
SuperSocket,supersocket.clientEngine,supersocket.protobase,supersocket.common
supersocket服務端幾個重要的物件:AppServer,Appsession,IRequestInfo,FixedHeaderReceiveFilter。下面就來分別介紹這幾個物件。
IRequestInfo是接收實際資料的介面,預設採用StringRequestInfo。我自己定義了一個接收自己的資料型別:
public class DataRequestInfo : IRequestInfo { public string Key { get; set; } public byte[] Data { get; set; } public byte[] DataSend { get; set; } public DataRequestInfo(string key,byte[] header, byteView Code Appsession:是連線伺服器的一個會話,支援繼承。當客戶端連線上服務端後,服務端就會產生一個Appsession[] bodyBuffer) { Key= key; int length = ByteConvertHelper.byteArrayToInt(header); Data = new byte[length]; Array.Copy(bodyBuffer, 0, Data, 0, length); DataSend=new byte[length+4]; Array.Copy(header, 0, DataSend, 0, header.Length); Array.Copy(bodyBuffer,0, DataSend, header.Length, bodyBuffer.Length); } }
public class PaintAppsession : AppSession<PaintAppsession, DataRequestInfo> { public string IDKey { get { return base.SessionID; } } // public string NickName { get; set; } public ClientPlayerInfo ClientPlayerInfo { get; set; } public bool isReady { get; set; } protected override void HandleException(Exception e) { // var a = e; } }View Code AppServer就表示服務端了,也支援繼承,AppServer這種是抽象類,必須自己繼承。
public class PaintAppServer : AppServer<PaintAppsession, DataRequestInfo> { public PaintAppServer(IReceiveFilterFactory<DataRequestInfo> protocol) : base(protocol) { } }View Code FixedHeaderReceiveFilter表示接收頭部固定長度的位元組,頭部header長度定義為4,每次傳送的位元組前4個的自己是可以自己定義的,比如存傳送的資料包的大小。這個類的作用是把從網路中收到的位元組組裝成DataRequestInfo。
internal class MyServerReceiveFilter : FixedHeaderReceiveFilter<DataRequestInfo> { public MyServerReceiveFilter(): base(4) { } protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length) { var data=new byte[length]; Array.Copy(header, offset, data, 0, length); var len = ByteConvertHelper.byteArrayToInt(data); return len; } protected override DataRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length) { var data = new byte[length]; Array.Copy(bodyBuffer.ToArray(), offset, data, 0, length); return new DataRequestInfo("key1",header.ToArray(), data); } public override DataRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) { return base.Filter(readBuffer, offset, length, toBeCopied, out rest); } }View Code
使用:
appServer = new PaintAppServer(new DefaultReceiveFilterFactory<MyServerReceiveFilter, DataRequestInfo>()); 配置監聽:IServerConfig m_Config = new ServerConfig { Port = port, Ip = "Any", MaxConnectionNumber = 1000, Mode = SocketMode.Tcp, Name = "CustomProtocolServer", MaxRequestLength = 10240 }; if (appServer.Setup(m_Config, logFactory: new ConsoleLogFactory())){;}View Code 開啟: appServer.Start();