6.14WebSocket 双工通信
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
WebSocket 双工通信#
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
WebSocket 的应用场景:
- 实时聊天应用:
WebSocket可以实现实时的消息传递,使得用户间的交流几乎无延迟。 - 在线游戏:对于需要快速响应的游戏,
WebSocket能够提供低延迟的数据传输。 - 股票市场更新:实时更新股票价格和其他金融信息。
- 协同编辑工具:允许多个用户同时编辑同一个文档,并实时看到其他人的更改。
- 实时地图应用:例如导航应用中实时交通状况的更新。
以下示例展示了如何使用 WebSocketClient 连接服务器:
using var webSocketClient = new WebSocketClient("wss://ws.postman-echo.com/raw"); // 支持 ws:// 和 wss://// 连接成功事件webSocketClient.Connected += (sender, s) =>{ Console.WriteLine("连接成功"); return Task.CompletedTask;};// 连接关闭事件webSocketClient.Closed += (sender, args) =>{ Console.WriteLine("连接关闭"); return Task.CompletedTask;};// 接收文本消息webSocketClient.TextReceived += (sender, s) =>{ Console.WriteLine(s.Message); return Task.CompletedTask;};// 接收二进制消息webSocketClient.BinaryReceived += (sender, s) =>{ Console.WriteLine(s.Message); return Task.CompletedTask;};// 连接服务器await webSocketClient.ConnectAsync();// 开启一个任务,循环发送消息_ = Task.Run(async () =>{ var i = 0; while (i < 5) { // 发送文本消息 await webSocketClient.SendAsync("Hello, WebSocket!"); await Task.Delay(1000); i++; } // 关闭连接 await webSocketClient.CloseAsync();});// 等待接收消息和关闭事件(阻塞)await webSocketClient.WaitAsync();WebSocket 与 Server-Sent Events (SSE) 的区别:
- 通信方向:
WebSocket支持全双工双向通信,SSE仅支持服务器向客户端单向推送数据。 - 协议:
WebSocket使用独立的WebSocket协议 (ws://或wss://),SSE基于HTTP协议。 - 握手过程:
WebSocket需要特殊的HTTP升级头来转换协议,SSE无需特殊握手,直接通过HTTP请求建立连接。 - 连接保持:
WebSocket连接保持直到显式关闭,SSE可能因网络问题断开,但浏览器会自动重连。 - 数据格式:
WebSocket支持多种数据格式,包括二进制数据,SSE数据格式较固定,通常是简单的文本消息。 - 跨域支持:
WebSocket建立连接时检查跨域策略,连接后不受限,SSE依赖于CORS策略。
选择使用 WebSocket 还是 SSE 主要取决于具体的应用需求:
- 如果需要实现双向通信或处理大量数据流,
WebSocket是更好的选择; - 如果只是需要服务器向客户端推送更新,且对数据格式要求不高,
SSE可能更加轻量和易于实现。
WebSocketClient 客户端#
框架内置了 WebSocketClient 类型,便于用户通过 ws 或 wss 协议与 WebSocket 服务器建立连接。要使用 WebSocket 功能,首先需要创建并初始化 WebSocketClient 的实例。以下详尽列出了 WebSocketClient 实例所具备的全部功能配置选项:
- 创建
WebSocketClient客户端
以下是创建 WebSocketClient 实例的三种方式,它们分别通过不同的构造函数重载实现,但实质上最终都调用了带有 WebSocketClientOptions 参数的构造函数来配置连接:
// 直接使用 URL 字符串(支持 ws:// 和 wss://)using var webSocketClient = new WebSocketClient("wss://localhost:7044/ws");// 使用 Uri 对象using var webSocketClient = new WebSocketClient(new Uri("wss://localhost:7044/ws"));// 使用 WebSocketClientOptions 对象进行详细配置using var webSocketClient = new WebSocketClient(new WebSocketClientOptions("wss://localhost:7044/ws"));// 配置内部 ClientWebSocketOptions 实例using var webSocketClient = new WebSocketClient("wss://localhost:7044/ws", options => {});WebSocketClientOptions 类型包含了多种配置属性,用于定制 ClientWebSocket 连接的详细设置。WebSocketClientOptions,包含以下属性:
- 属性:
ServerUri:服务器地址(Uri类型)。ReconnectInterval:重连的间隔时间(毫秒),默认值为2秒。(TimeSpan类型)。MaxReconnectRetries:最大重连次数,默认10次。(int类型)。Timeout:超时时间(TimeSpan类型)。ReceiveBufferSize:接收服务器新消息缓冲区大小(以字节为单位的int类型)。Configure:用户配置内部ClientWebSocketOptions实例(Action<ClientWebSocketOptions>类型)。
WebSocketClient客户端事件
WebSocketClient 客户端提供了多种事件,允许开发者在 WebSocket 通信的各个阶段插入自定义逻辑。以下示例展示了如何订阅这些事件:
using var webSocketClient = new WebSocketClient("wss://localhost:7044/ws"); // 支持 ws:// 和 wss://// 开始连接时触发事件webSocketClient.Connecting += (s, e) => {};// 连接成功时触发事件webSocketClient.Connected += (s, e) => { };// 开始重新连接时触发事件webSocketClient.Reconnecting += (s, e) => { };// 重新连接成功时触发事件webSocketClient.Reconnected += (s, e) => { };// 开始关闭连接时触发事件webSocketClient.Closing += (s, e) => { };// 关闭连接成功时触发事件webSocketClient.Closed += (s, e) => { };// 开始接收消息时触发事件webSocketClient.ReceivingStarted += (s, e) => { };// 停止接收消息时触发事件webSocketClient.ReceivingStopped += (s, e) => { };// 接收文本消息事件,result 为 WebSocketTextReceiveResult 类型webSocketClient.TextReceived += (s, result) => { };// 接收二进制消息事件,result 为 WebSocketBinaryReceiveResult 类型webSocketClient.BinaryReceived += (s, result) => { };WebSocketTextReceiveResult 类型派生自 WebSocketReceiveResult ,包含以下属性:
- 属性:
Message:文本消息(string类型)。- 其他属性参考 WebSocketReceiveResult
WebSocketBinaryReceiveResult 类型派生自 WebSocketReceiveResult ,包含以下属性:
- 属性:
Message:二进制消息(byte[]类型)。- 其他属性参考 WebSocketReceiveResult
WebSocketClient 客户端方法
WebSocketClient 类封装了与 WebSocket 服务器进行交互的关键操作,具体包括连接、发送消息和关闭连接三种方法。
using var webSocketClient = new WebSocketClient("wss://localhost:7044/ws"); // 支持 ws:// 和 wss://// 连接服务器await webSocketClient.ConnectAsync(cancellationToken);// 向服务器发送消息await webSocketClient.SendAsync(message, endOfMessage, cancellationToken); // 发送字符串消息await webSocketClient.SendAsync(byteArray, endOfMessage, cancellationToken); // 发送二进制消息await webSocketClient.SendAsync(message, webSocketMessageType, endOfMessage, cancellationToken); // 发送指定类型的消息(文本或二进制)// 等待消息(阻塞)await webSocketClient.WaitAsync(cancellationToken);// 关闭连接await webSocketClient.CloseAsync(cancellationToken); // 无附加信息关闭await webSocketClient.CloseAsync(closeStatus, closeDescription, cancellationToken); // 提供关闭状态和描述信息关闭