跨平台 WebSocket 服务器的设计与实现 —— 基于.NET 8 的跨操作系统解决方案linux,macos,windows——开发工具
代码
using System.Net;using System.Net.WebSockets;using System.Text;using System.Threading.Channels;var cts = new CancellationTokenSource();Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cts.Cancel();};var listener = new HttpListener();listener.Prefixes.Add(\"http://localhost:10086/\");listener.Start();Console.WriteLine(\"WebSocket 服务器已启动,监听地址: http://localhost:10086/\");try{ await AcceptClientsAsync(listener, cts.Token);}catch (OperationCanceledException){ Console.WriteLine(\"服务器正在关闭...\");}finally{ listener.Close(); Console.WriteLine(\"WebSocket 服务器已停止\");}async Task AcceptClientsAsync(HttpListener listener, CancellationToken cancellationToken){ var clients = new List(); while (!cancellationToken.IsCancellationRequested) { try { var context = await listener.GetContextAsync().WaitAsync(cancellationToken); if (context.Request.IsWebSocketRequest) { var webSocketContext = await context.AcceptWebSocketAsync(null); var clientEndpoint = context.Request.RemoteEndPoint; Console.WriteLine($\"客户端连接来自: {clientEndpoint}\"); var clientTask = HandleClientAsync( webSocketContext.WebSocket, clientEndpoint, cancellationToken); clients.Add(clientTask); // 清理已完成的客户端任务 clients = clients.Where(t => !t.IsCompleted).ToList(); } else { context.Response.StatusCode = 400; context.Response.Close(); } } catch (Exception ex) when (ex is not OperationCanceledException) { Console.WriteLine($\"处理客户端连接时出错: {ex.Message}\"); } } // 等待所有客户端连接关闭 await Task.WhenAll(clients);}async Task HandleClientAsync(WebSocket webSocket, IPEndPoint clientEndpoint, CancellationToken cancellationToken){ try { var buffer = WebSocket.CreateClientBuffer(4096, 4096); while (webSocket.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested) { var receiveResult = await webSocket.ReceiveAsync(buffer, cancellationToken); if (receiveResult.MessageType == WebSocketMessageType.Text) { var message = Encoding.UTF8.GetString(buffer.Array!, 0, receiveResult.Count); Console.WriteLine($\"从 {clientEndpoint} 收到消息: {message}\"); var responseMessage = $\"收到 {clientEndpoint} 的消息: {message}\"; var responseBuffer = Encoding.UTF8.GetBytes(responseMessage); await webSocket.SendAsync( new ArraySegment(responseBuffer), WebSocketMessageType.Text, true, cancellationToken); } else if (receiveResult.MessageType == WebSocketMessageType.Close) { await webSocket.CloseAsync( WebSocketCloseStatus.NormalClosure, \"客户端请求关闭\", cancellationToken); Console.WriteLine($\"客户端 {clientEndpoint} 已断开连接\"); break; } } } catch (OperationCanceledException) { Console.WriteLine($\"客户端 {clientEndpoint} 连接被取消\"); } catch (Exception ex) { Console.WriteLine($\"处理客户端 {clientEndpoint} 消息时出错: {ex.Message}\"); } finally { webSocket?.Dispose(); }}
阿雪技术观
在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者。无论是分享代码、撰写技术博客,还是参与开源项目维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基生命,为科技进步添砖加瓦。
Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don\'t just be the one reaping all the benefits; step up and be a contributor too. Whether you\'re tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We\'re gonna team up and explore the whole silicon - based life thing, and in the process, we\'ll be fueling the growth of technology.