Skip to main content

创建WebSocket客户端

一、可配置项

继承HttpClient

二、支持插件接口

支持ITcpPlugin、IWebSocketPlugin

声明自定义实例类,然后实现IWebSocketPlugin接口,即可实现下列事务的触发。或者继承自WebSocketPluginBase类,重写相应方法即可。

插件方法功能
OnHandshaking当发送握手请求之前
OnHandshaked当收成功的握手响应之后
OnHandleWSDataFrame当收到Websocket的数据报文
OnClosing当收到关闭请求时

三、创建WS客户端

3.1 创建常规客户端

WebSocketClient myWSClient = new WebSocketClient();
myWSClient.Setup(new TouchSocketConfig()
.SetRemoteIPHost("ws://127.0.0.1:7789/ws")
.ConfigureContainer(a =>
{
a.AddConsoleLogger();
}));
myWSClient.Connect();
myWSClient.Logger.Message("连接成功");

3.2 创建WSs客户端

当需要连接到由证书机构颁发的网址(例如:小程序、物联网等)时,仅需要设置url即可。

wss://127.0.0.1:7789/ws

当连接自定义证书的Ssl:wss://127.0.0.1:7789/ws

WebSocketClient myWSClient = new WebSocketClient();

myWSClient.Setup(new TouchSocketConfig()
.SetRemoteIPHost(new IPHost("wss://127.0.0.1:7789/ws"))
.SetClientSslOption(
new ClientSslOption()
{
ClientCertificates = new X509CertificateCollection() { new X509Certificate2("RRQMSocket.pfx", "RRQMSocket") },
SslProtocols = SslProtocols.Tls12,
TargetHost = "127.0.0.1",
CertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return true; }
}))
.Connect();

Console.WriteLine("连接成功");
注意

当使用域名连接时,TargetHost为域名,例如连接到IPHost("ws://baidu.com")时,TargetHost应当填写:baidu.com

四、发送数据

因为客户端是从HttpClientBase派生,则可以直接使用扩展方法,进行发送。

4.1 发送文本类消息

myWSClient.SendWithWS("Text");

4.2 发送二进制消息

myWSClient.SendWithWS(new byte[10]);

4.3 发送分包的二进制

例如:发送的数据为{0,1,2,3,4,5,6,7,8,9},当设置packageSize为5时,会先发送{0,1,2,3,4}作为头包,然后发送{5,6,7,8,9}的后继包。

byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
myWSClient.SubSendWithWS(data, 5);

4.4 直接发送自定义构建的数据帧

WSDataFrame frame=new WSDataFrame();
frame.Opcode= WSDataType.Text;
frame.FIN= true;
frame.RSV1= true;
frame.RSV2= true;
frame.RSV3= true;
frame.AppendText("I");
frame.AppendText("Love");
frame.AppendText("U");
myWSClient.SendWithWS(frame);
备注

此部分功能就需要你对Websocket有充分了解才可以操作。

注意

Websocket的所有发送,都是形如SendWithWS的扩展方法。不可直接Send。

五、接收数据

5.1 订阅Received事件实现

client.Received = (c, e) =>
{
switch (e.Opcode)
{
case WSDataType.Cont:
break;
case WSDataType.Text:
break;
case WSDataType.Binary:
break;
case WSDataType.Close:
break;
case WSDataType.Ping:
break;
case WSDataType.Pong:
break;
default:
break;
}
};

5.2 使用插件实现。

【定义插件】

class MyWSClientPlugin:WebSocketPluginBase<WebSocketClient>
{
protected override void OnHandleWSDataFrame(WebSocketClient client, WSDataFrameEventArgs e)
{
switch (e.DataFrame.Opcode)
{
case WSDataType.Cont:
client.Logger.Info($"收到中间数据,长度为:{e.DataFrame.PayloadLength}");
break;

case WSDataType.Text:
client.Logger.Info(e.DataFrame.ToText());
break;

case WSDataType.Binary:
if (e.DataFrame.FIN)
{
client.Logger.Info($"收到二进制数据,长度为:{e.DataFrame.PayloadLength}");
}
else
{
client.Logger.Info($"收到未结束的二进制数据,长度为:{e.DataFrame.PayloadLength}");
}
break;

case WSDataType.Close:
{
client.Logger.Info("远程请求断开");
client.Close("断开");
}

break;

case WSDataType.Ping:
break;

case WSDataType.Pong:
break;

default:
break;
}
}
}

【使用】

WebSocketClientmyWSClient = new WebSocketClient();
myWSClient.Setup(new TouchSocketConfig()
.SetRemoteIPHost("ws://127.0.0.1:7789/ws")
.UsePlugin()
.ConfigureContainer(a =>
{
a.AddFileLogger();
})
.ConfigurePlugins(a =>
{
a.Add<MyWSClientPlugin>();
}));
myWSClient.Connect();

六、关闭连接

关闭Websocket,应该发送关闭报文。

myWSClient.CloseWithWS("close");