为什么WebSockets是您必须尝试的魔法
\n\n想象一下:您打开了一个加密货币价格网站。价格每秒都在跳动。或者是一个在线聊天室,消息瞬间送达,无需“刷新页面”。这是如何工作的?过去,浏览器会不断向服务器发送请求:“嘿,有什么新消息吗?”——而服务器则会回答:“没有,去睡觉吧。”这被称为HTTP轮询。它速度慢,消耗流量,并且给服务器带来负担。
\n\nWebSockets就像一条开放的通信通道。服务器可以主动告诉客户端:“看,有更新!”——无需多余的请求。在C#中使用WebSockets不仅方便,而且优雅。.NET生态系统提供了现成的工具:从原生类System.Net.WebSockets到强大的SignalR。
在本文中,我们不仅会讨论理论。我们将编写两个实际项目:实时聊天室和股票监控器。您将看到如何创建C# WebSocket服务器并将客户端连接到它。我们开始吧!
\n\n什么是WebSockets,为什么C#是理想选择
\n\nWebSocket是一种基于TCP的双向通信协议。在握手之后,连接保持打开状态。数据在两端之间传输,无需HTTP头部。这带来了:
\n\n- \n
- 速度——毫秒级的延迟。 \n
- 资源节省——一个连接代替数百个请求。 \n
- 真正的实时性——服务器可以主动发起发送。 \n
在这方面,C#堪称重型武器。ASP.NET Core原生支持WebSockets。此外,异步编程(async/await)与通道工作模型完美契合。您在等待消息时不会阻塞线程——这使得代码既高效又易读。
\n\n第一个项目:基于WebSockets的实时聊天室
\n\n我们从经典项目——聊天室开始。它能清晰地展示整个机制:连接、发送、接收和关闭连接。
\n\n步骤1:创建C# WebSocket服务器
\n\n打开Visual Studio或终端。创建一个新的ASP.NET Core Web API项目(或空项目)。如果需要,安装以下包:
\n\ndotnet add package Microsoft.AspNetCore.WebSockets\n\n现在,在Program.cs中配置中间件。以下是服务器的最小代码:
var builder = WebApplication.CreateBuilder(args);\nbuilder.Services.AddWebSockets(options => { });\nvar app = builder.Build();\n\napp.UseWebSockets();\n\n// 用于存储所有已连接客户端的列表\nvar clients = new List<System.Net.WebSockets.WebSocket>();\n\napp.Map("/chat", async (HttpContext context) =>\n{\n if (context.WebSockets.IsWebSocketRequest)\n {\n var webSocket = await context.WebSockets.AcceptWebSocketAsync();\n clients.Add(webSocket);\n Console.WriteLine("新客户端已连接!");\n\n // 用于接收数据的缓冲区\n var buffer = new byte[1024 * 4];\n while (webSocket.State == WebSocketState.Open)\n {\n var result = await webSocket.ReceiveAsync(\n new ArraySegment<byte>(buffer), CancellationToken.None);\n \n if (result.MessageType == WebSocketMessageType.Close)\n {\n await webSocket.CloseAsync(\n WebSocketCloseStatus.NormalClosure, \n "连接已关闭", CancellationToken.None);\n clients.Remove(webSocket);\n Console.WriteLine("客户端已断开。");\n }\n else if (result.MessageType == WebSocketMessageType.Text)\n {\n // 从一个客户端接收消息\n var message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);\n Console.WriteLine($"收到: {message}");\n\n // 广播给所有其他客户端\n v