创建WebSocket客户端
定义
TouchSocket.HttpTouchSocket.Http.WebSocketsdotnet add package TouchSocket.Http一、说明
WebSocketClient是WebSocket系客户端基类,它直接参与WebSocket的连接、握手、发送、接收、处理、断开等。它基于HTTP协议升级而来,与服务器的HttpSessionClient中的WebSocket实例是一一对应的通信关系。
二、特点
- 简单易用,支持ws和wss协议。
- 支持自定义握手请求头。
- 内置心跳机制(Ping/Pong)。
- 支持文本和二进制数据传输。
- 支持大数据包的中继传输。
- 支持断线重连机制。
- 内存池支持,高性能处理。
- 基于委托、插件驱动,支持AOP编程。
三、产品应用场景
- 实时通信应用:聊天室、在线客服、即时消息推送。
- 在线协作:多人在线编辑、实时数据同步。
- 物联网通信:设备状态监控、远程控制。
- 游戏开发:实时游戏数据交换。
- 金融交易:实时股票行情、交易数据推送。
- 实时监控:系统监控、数据大屏展示。
四、可配置项
WebSocketClient继承自HttpClient,所以支持所有HttpClient的配置项,无特有配置。
五、支持插件接口
| 插件方法 | 功能 |
|---|---|
| IWebSocketConnectingPlugin | 当收到握手请求之前,可以进行连接验证、自定义请求头等 |
| IWebSocketConnectedPlugin | 当成功握手响应之后触发 |
| IWebSocketReceivedPlugin | 当收到WebSocket的数据报文时触发 |
| IWebSocketClosingPlugin | 当收到关闭请求时触发,如果对方直接断开连接,此方法则不会触发 |
| IWebSocketClosedPlugin | 当WebSocket连接断开时触发,无论是否正常断开。但如果是断网等操作,可能不会立即执行,需要结合心跳操作和CheckClear插件来进行清理 |
六、创建WebSocket客户端
6.1 简单创建
简单的处理逻辑可通过Received等委托直接实现。
6.2 继承实现
一般继承实现的话,可以从WebSocketClient继承。
6.3 创建WSS客户端
当需要连接到由证书机构颁发的网址(例如:小程序、物联网等)时,仅需要设置带有wss的url即可。当需要连接到自签名证书的网站时,则需要额外设置,详情请参考HttpClient证书配置。
七、连接服务器
WebSocketClient可以使用默认配置直接连接到服务器,同时也支持使用多种方法定义连接。
7.1 直接连接
使用url直接建立连接,这一般是服务器也只是普通的ws服务器的情况下。
7.2 带Query参数连接
带Query参数连接,实际上还是通过url直接连接。
7.3 使用特定Header连接
一般的,当某些服务器安全级别较高时,可能会定制特定的header用于验证连接。
7.4 使用Post方式连接
WebSocket默认情况下是基于Get方式连接的,但是在一些更特殊的情况下,需要以Post,甚至其他方式连接,那么可以使用以下方式实现。
使用此方式时,基本上就能完全定制请求连接了。比如一些Cookie等。
八、接收数据
在WebSocketClient中,接收数据的方式有很多种。多种方式可以组合使用。
8.1 Received委托处理
当使用WebSocketClient创建客户端时,内部已经定义好了一个外置委托Received,可以通过该委托直接接收数据。
8.2 继承WebSocketClient重写接收逻辑
如6.2所示,如果需要更自定义的接收逻辑,可以从WebSocketClient继承,然后重写OnWebSocketReceived方法。
8.3 使用插件接收数据
使用插件接收消息是最推荐的方式,它提供了高度解耦和灵活的数据处理能力。
(1)定义插件:
(2)配置使用插件:
在客户端端,默认情况下插件的所有函数都是线程安全的。
8.4 异步阻塞接收
异步阻塞接收是通过直接调用WebSocket的ReadAsync方法来同步阻塞式读取数据。这种方式的特点是能在代码上下文中直接获取数据,便于处理复杂的数据逻辑。
一般的,在刚连接成功调用ReadAsync方法来接收数据。
ReadAsync方式是异步非阻塞的接收方式,不会占用线程资源,只会阻塞当前Task。因此可以大量使用,不需要考虑性能问题。
使用ReadAsync方式会终止触发IWebSocketReceivedPlugin插件。
8.5 接收中继数据
WebSocket在接收大数据时,可能会分包接收。可以通过WSDataFrame.Opcode的值是不是WSDataType.Cont来判断是不是分包数据。
分包数据的处理方式有很多,下面提供一种内存缓存的方式:
内存缓存的方式适合数据量不大的场景,如果数据量较大,建议使用其他缓存等方式。
九、发送数据
客户端定义了一些发送方法,方便开发者快速发送数据。
9.1 发送文本消息
9.2 发送二进制消息
9.3 发送自定义数据帧
此部分功能需要对WebSocket协议有充分了解才可以操作。
9.4 发送Ping、Pong消息
WebSocket是双向通讯,所以支持客户端和服务器双向操作Ping和Pong报文。但是一般来说都是客户端执行Ping,服务器回应Pong。
9.5 发送大数据(分包)
发送大数据时,可能需要分包发送,可以使用SendAsync的重载方法,设置FIN标志。
十、连接管理
10.1 连接状态检查
WebSocket拥有独立的握手机制,可以通过Online属性检查连接状态。
10.2 关闭连接
在使用WebSocket时,如果想主动关闭连接,可以使用CloseAsync方法,同时可以携带一个关闭原因。
默认关闭状态码为1000,意为:正常关闭。
10.3 断线重连
WebSocket断线重连,可以直接使用插件。详情请参考断线重连配置。