由於需要在服務端和客戶端持續通信,於是在網上找了好久的socket通信工具。剛開始想直接用.net自帶的socket通信,后來擔心不夠穩定健壯,畢竟自己不專業。找來找去覺得supersocket還可以,但是說實話,他們的幫助文檔寫的真是太爛了,使用也不夠簡單易懂,折騰了一陣大致明白如何使用。
1,在nuget上引用supersocket.clientengine和supersocket.protobase
2,定義一個filter的類,protobase提供了5種預定義的方式,這里采用第二種,即定義數據頭和尾的方式:
TerminatorReceiveFilterBeginEndMarkReceiveFilterFixedHeaderReceiveFilterFixedSizeReceiveFilterCountSpliterReceiveFilter
class MyBeginEndMarkReceiveFilter : BeginEndMarkReceiveFilter<StringPackageInfo>
{
public MyBeginEndMarkReceiveFilter(string begin,string end)
: base(Encoding.UTF8.GetBytes(begin), Encoding.UTF8.GetBytes(end))
{
this.begin = begin;
this.end = end;
}
string begin;
string end;
public override StringPackageInfo ResolvePackage(IBufferStream bufferStream)
{
//獲取接收到的完整數據,包括頭和尾
var body = bufferStream.ReadString((int)bufferStream.Length, Encoding.ASCII);
//掐頭去尾,只返回中間的數據
body = body.Remove(body.Length - end.Length, end.Length);
body = body.Remove(0, begin.Length);
return new StringPackageInfo("", body, new string[] { });
}
}
3,封裝一個簡單的類。初始化類的時候設置好ip,端口,數據頭和尾,然后設置要發送的數據屬性data,然后調用startcomm方法開始每秒發送一次請求數據到服務器,訂閱接收數據的事件newReceived。如果有需要可以隨時更換data的內容,或者調用stopcomm停止發送數據
class socketClient
{
SuperSocket.ClientEngine.EasyClient client;
/// <summary>
/// 定義服務端的ip地址和端口,以及接收數據的頭和尾,只有在頭和尾之間的數據才算有效數據
/// </summary>
/// <param name="ip">ip地址</param>
/// <param name="port">服務端口</param>
/// <param name="startFilter">數據頭</param>
/// <param name="endFilter">數據尾</param>
public socketClient(string ip, int port, string startFilter, string endFilter)
{
this.ip = ip;
this.port = port;
if (!string.IsNullOrEmpty(startFilter)) this.startFilter = startFilter;
if (!string.IsNullOrEmpty(endFilter)) this.endFilter = endFilter;
client = new SuperSocket.ClientEngine.EasyClient();
client.Initialize(new MyBeginEndMarkReceiveFilter(this.startFilter,this.endFilter), onReceived);
}
string ip;
int port;
string startFilter = "!!!";
string endFilter = "###";
bool cycleSend = false;
/// <summary>
/// 要發送到服務端的數據
/// </summary>
public string data { get; set; } = "hello,this is super client\r\n";
public void startComm()
{//開始循環發送數據
cycleSend = true;
System.Threading.Thread _thread = new System.Threading.Thread(sendData);
_thread.IsBackground = true;
_thread.Start();
}
public void sendData()
{//采用線程間隔一秒發送數據,防止界面卡死
while (cycleSend)
{
if (!client.IsConnected)
{
connectToServer(ip, port);
}
if (client.IsConnected)
{
client.Send(Encoding.ASCII.GetBytes("hello,this is super client\r\n"));
}
System.Threading.Thread.Sleep(1000);
}
}
public void stopComm()
{//停止循環發送數據
cycleSend = false;
}
public async void connectToServer(string ip, int port)
{//連接到服務端
var connected = await client.ConnectAsync(new IPEndPoint(IPAddress.Parse(ip), port));
if (connected)
{
//發送連接信息
client.Send(Encoding.ASCII.GetBytes("build connection"));
}
}
public System.EventHandler newReceived;
private void onReceived(StringPackageInfo stringPackageInfo)
{//當讀取到數據,觸發一個事件,方便外部接收數據
if (newReceived != null)
{
newReceived(stringPackageInfo.Body, new EventArgs());
}
}
}
