WebSocket在C#中:从A到Z的实时应用程序

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么WebSocket是实时应用程序的标准?



现代Web应用程序需要对用户操作做出即时响应。无论是在线聊天、股票交易终端、多人在线游戏还是监控系统——数据传输的延迟都是不可接受的。传统的HTTP协议基于“请求-响应”模式,对于此类场景效率低下:客户端必须不断轮询服务器,造成不必要的负载。



WebSocket应运而生——这是一种在客户端和服务器之间提供持久双向连接的协议。在本文中,我们将探讨如何使用C#(.NET)创建实时应用程序,从简单的回显服务器到完整的聊天系统。您将了解协议的工作原理、.NET平台提供的工具,以及如何避免常见错误。



.NET中WebSocket的基础:服务器端



.NET平台通过System.Net.WebSockets命名空间提供对WebSocket的内置支持。让我们看看如何基于ASP.NET Core创建服务器。



1. 配置WebSocket中间件



首先,需要在请求处理管道中添加WebSocket支持。在Program.cs文件中:



var builder = WebApplication.CreateBuilder(args);var app = builder.Build();

app.UseWebSockets(); // 启用WebSocket支持

app.Map("/ws", async (HttpContext context) =>{ if (context.WebSockets.IsWebSocketRequest) { using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); await Echo(webSocket); } else { context.Response.StatusCode = 400; }});

app.Run("http://localhost:5000");

async Task Echo(WebSocket webSocket){ var buffer = new byte[1024 * 4]; var receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None);

while (!receiveResult.CloseStatus.HasValue) { // 将接收到的数据发送回客户端(回显) await webSocket.SendAsync( new ArraySegment<byte>(buffer, 0, receiveResult.Count), receiveResult.MessageType, receiveResult.EndOfMessage, CancellationToken.None);

receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None); }

await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None);}


这段代码创建了一个回显服务器:客户端发送的所有内容都会被返回。请注意使用async/await——与WebSocket的交互始终是异步的。



2. 管理多个连接



在实际应用程序中,需要管理多个连接。让我们创建一个简单的连接管理器:



public class WebSocketConnectionManager{    private readonly ConcurrentDictionary<string, WebSocket> _connections = new();

public string AddConnection(WebSocket socket) { var id = Guid.NewGuid().ToString(); _connections.TryAdd(id, socket); return id; }

public async Task BroadcastMessageAsync(string message) { var tasks = _connections.Values.Select(async socket => { if (socket.State == WebSocketState.Open) { var bytes = Encoding.UTF8.GetBytes(message); await socket.SendAsync( new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None); } }); await Task.WhenAll(tasks); }}


这个类允许存储所有活动连接并广播消息

博客

书籍推荐