.Net WebSocket Server运行成功后,如何实现消息收发?是否需创建客户端?
.NET WebSocket Server 消息收发与客户端实现指南
一、先理清核心逻辑
- 消息发送目标:WebSocket是客户端-服务器双向通信,服务器发消息要发给已连接的
Client.cs实例;客户端发的消息会被服务器监听处理。 - 是否要自己做客户端:是的,你手里只有服务端代码,必须写客户端(或者用现成测试工具)才能完成完整通信。
二、基于现有代码的实操步骤
1. 给服务器加消息监听
打开Server.cs,找到连接建立后的处理逻辑(比如OnWebSocketConnected这类方法),加消息接收逻辑:
// 示例:在Server类里处理客户端消息 private async Task HandleClientMessages(Client client) { var buffer = new byte[1024 * 4]; WebSocketReceiveResult result; // 持续监听客户端消息 do { result = await client.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Text) { string receivedMsg = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.WriteLine($"收到客户端 {client.Id} 的消息:{receivedMsg}"); // 示例:给这个客户端回消息 await SendToSingleClient(client, $"服务器已收到:{receivedMsg}"); } } while (!result.CloseStatus.HasValue); // 处理客户端断开 await client.WebSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); _connectedClients.Remove(client); } // 封装给单个客户端发消息的方法 private async Task SendToSingleClient(Client client, string msg) { if (client.WebSocket.State == WebSocketState.Open) { var buffer = Encoding.UTF8.GetBytes(msg); await client.WebSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None); } }
同时在Server.cs里维护一个List<Client> _connectedClients集合,用来管理所有在线客户端。
2. 实现服务器主动推送(广播)
如果需要给所有在线客户端发消息,在Server.cs加个广播方法:
public async Task Broadcast(string msg) { var buffer = Encoding.UTF8.GetBytes(msg); // 用ToList避免遍历中集合变更报错 foreach (var client in _connectedClients.ToList()) { if (client.WebSocket.State == WebSocketState.Open) { await client.WebSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None); } } }
之后可以在Program.cs里调用这个方法,比如定时推送或者触发事件时推送。
3. 做客户端测试
两种简单方式:
方式1:.NET控制台客户端
新建控制台项目,写以下代码:
using System.Net.WebSockets; using System.Text; var client = new ClientWebSocket(); // 替换成你的服务器地址和端口 await client.ConnectAsync(new Uri("ws://localhost:5000/ws"), CancellationToken.None); Console.WriteLine("已连到服务器"); // 后台监听服务器消息 _ = Task.Run(async () => { var buffer = new byte[1024 * 4]; WebSocketReceiveResult result; do { result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); string msg = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.WriteLine($"收到服务器消息:{msg}"); } while (!result.CloseStatus.HasValue); }); // 输入消息发给服务器 string input; do { input = Console.ReadLine(); if (!string.IsNullOrEmpty(input)) { var buffer = Encoding.UTF8.GetBytes(input); await client.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None); } } while (input != "exit"); await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "客户端主动断开", CancellationToken.None);
方式2:浏览器控制台测试
打开浏览器F12控制台,输入:
const ws = new WebSocket('ws://localhost:5000/ws'); ws.onopen = () => { console.log('连接成功'); ws.send('Hello Server!'); }; ws.onmessage = (event) => { console.log('收到服务器消息:', event.data); }; // 发消息直接用:ws.send('你的内容');
4. 整合现有代码
检查你拿到的Client.cs,应该已经封装了WebSocket实例和客户端ID,把上面的收发逻辑整合到Server.cs对应方法里就行。比如服务器启动后,每有新客户端连接,就启动HandleClientMessages任务。
三、常见坑点
- 确保服务器监听的地址端口和客户端连接的URI一致。
- 只有当WebSocket状态是
WebSocketState.Open时才能收发消息,否则会报错。 - 浏览器测试注意跨域:如果服务器和前端不在同一域名,需要在服务端配置跨域允许。
内容的提问来源于stack exchange,提问作者Hasan Ozan
相关产品推荐
相关产品推荐

