通信协议—WebSocket

ops/2025/1/23 9:56:14/

一、WebSocket编程概念

1.1 什么是WebSocket

WebSocket 是一种全双工通信协议,允许在客户端(通常是浏览器)和服务器之间建立持久连接,以实现实时的双向通信。它是 HTML5 标准的一部分,相比传统的 HTTP 请求,WebSocket 提供了更低的延迟和更高的性能,特别适合于需要实时更新数据的应用程序,如在线聊天、实时监控、游戏等

1.2 WebSocket的基本使用步骤

1.2.1 )服务器
1.2.1.1)使用System.Net.WebSocket命名空间
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
1.2.1.2) 创建WebSocket服务器端点
public async Task HandleWebSocketConnection(HttpContext context)
{if (context.WebSockets.IsWebSocketRequest){WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();await EchoWebSocket(webSocket);}else{context.Response.StatusCode = 400;}
}
1.2.1.3)处理WebSocket消息
private async Task EchoWebSocket(WebSocket webSocket)
{var buffer = new byte[1024 * 4];WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);while (!result.CloseStatus.HasValue){// 发送接收到的消息回客户端await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);// 继续接收下一条消息result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);}// 关闭 WebSocket 连接await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
1.2.1.4)启动服务器
public static async Task Main(string[] args)
{var webSocketServer = new WebSocketServer();await webSocketServer.Start();
}
1.2.2 )客户端
1.2.2.1)使用System.Net.WebSocket.ClientWebSocket 命名空间
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
1.2.2.2)创建WebSocket客户端并连接到服务器
public async Task ConnectToWebSocketServer()
{using (var clientWebSocket = new ClientWebSocket()){Uri serverUri = new Uri("ws://localhost:8080/ws");await clientWebSocket.ConnectAsync(serverUri, CancellationToken.None);await SendAndReceiveData(clientWebSocket);}
}
1.2.2.3)发送和接收数据
private async Task SendAndReceiveData(ClientWebSocket clientWebSocket)
{var buffer = new byte[1024 * 4];string message = "Hello, WebSocket Server!";var sendBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(message));await clientWebSocket.SendAsync(sendBuffer, WebSocketMessageType.Text, true, CancellationToken.None);WebSocketReceiveResult result = await clientWebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);string receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);Console.WriteLine($"Received: {receivedMessage}");
}
1.2.2.4)启动客户端
public static async Task Main(string[] args)
{var webSocketClient = new WebSocketClient();await webSocketClient.ConnectToWebSocketServer();
}
1.2.3) 运行步骤

1.2.3.1)先启动服务器程序,服务器将开始监听请求。
1.2.3.2)再启动客户端程序,客户端会连接到服务器并发送一条消息。
1.2.3.3)服务器接收到消息后,打印消息并回复。
1.2.3.4)客户端接收到服务器的回复并打印。

1.3 完整代码示例

1.3.1)服务器
using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;namespace WebSocketServerExample
{public class WebSocketServer{private readonly IWebHost _webHost;public WebSocketServer(){_webHost = new WebHostBuilder().UseKestrel().ConfigureServices(services => services.AddRouting()).Configure(app =>{app.UseWebSockets();app.Use(async (context, next) =>{if (context.WebSockets.IsWebSocketRequest){WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();await EchoWebSocket(webSocket);}else{context.Response.StatusCode = 400;}});}).Build();}public async Task Start(){await _webHost.StartAsync();}private async Task EchoWebSocket(WebSocket webSocket){var buffer = new byte[1024 * 4];WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);while (!result.CloseStatus.HasValue){// 发送接收到的消息回客户端await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);// 继续接收下一条消息result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);}// 关闭 WebSocket 连接await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);}}class Program{static async Task Main(string[] args){var webSocketServer = new WebSocketServer();await webSocketServer.Start();}}
}// 代码解释
// 创建 WebSocket 服务器端点:
// app.UseWebSockets();:启用 WebSocket 中间件。
// context.WebSockets.IsWebSocketRequest:检查请求是否为 WebSocket 请求。
// context.WebSockets.AcceptWebSocketAsync():接受 WebSocket 请求并创建 WebSocket 对象。// 处理 WebSocket 消息:
// await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);:接收客户端发送的消息。
// await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);:将接收到的消息发送回客户端。
// await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);:当收到关闭请求时,关闭连接。

 

1.3.2)客户端
using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using System.Text;namespace WebSocketClientExample
{public class WebSocketClient{public async Task ConnectToWebSocketServer(){using (var clientWebSocket = new ClientWebSocket()){Uri serverUri = new Uri("ws://localhost:8080/ws");await clientWebSocket.ConnectAsync(serverUri, CancellationToken.None);await SendAndReceiveData(clientWebSocket);}}private async Task SendAndReceiveData(ClientWebSocket clientWebSocket){var buffer = new byte[1024 * 4];string message = "Hello, WebSocket Server!";var sendBuffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(message));await clientWebSocket.SendAsync(sendBuffer, WebSocketMessageType.Text, true, CancellationToken.None);WebSocketReceiveResult result = await clientWebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);string receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);Console.WriteLine($"Received: {receivedMessage}");}}class Program{static async Task Main(string[] args){var webSocketClient = new WebSocketClient();await webSocketClient.ConnectToWebSocketServer();}}
}// 代码解释
// 创建 WebSocket 客户端并连接到服务器:
// new ClientWebSocket():创建 WebSocket 客户端对象。
// clientWebSocket.ConnectAsync(serverUri, CancellationToken.None);:连接到服务器。发送和接收数据:
// await clientWebSocket.SendAsync(sendBuffer, WebSocketMessageType.Text, true, CancellationToken.None);:向服务器发送消息。
// await clientWebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);:接收服务器的消息。

1.4 注意事项

1.4.1)端口号和URI : 确保服务器和客户端使用相同的端口号和URI路径

1.4.2)异常处理 :在实际应用中,需要添加适当的异常处理代码,例如处理连接失败、接收或发送消息时的异常等

1.4.3)多客户端处理 :上述服务器端代码仅处理一个客户端,对于多客户端场景,需要使用更复杂的逻辑,例如使用  ConcurrentDictionary  来管理多个客户端连接


http://www.ppmy.cn/ops/152435.html

相关文章

Hadoop 与 Spark:大数据处理的比较

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

初始JavaEE篇 —— 快速上手 SpringBoot

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 SpringBoot 相关介绍与解惑 SpringBoot 项目的创建 通过 官方提供的网页 来创建 通过 IDEA 来创建 SpringBoot 项目的介…

基于微信小程序的安心陪诊管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

微服务与docker

准备工作 在课前资料中给大家提供了黑马商城项目的资料,我们需要先导入这个单体项目。不过需要注意的是,本篇及后续的微服务学习都是基于Centos7系统下的Docker部署,因此你必须做好一些准备: Centos7的环境及一个好用的SSH客户端装好Docker会使用Docker如果是学习过上面Doc…

从大型企业到中小企业:销售易、红圈、励销云CRM的行业应用

在数字化转型的浪潮中&#xff0c;客户关系管理&#xff08;CRM&#xff09;系统已成为企业提升竞争力的关键工具。本文将对国内三大知名CRM品牌——销售易CRM、红圈CRM和励销云CRM进行深度分析&#xff0c;从品牌介绍和适用企业两个维度进行总结和盘点&#xff0c;帮助企业选择…

使用EasyExcel(FastExcel) 的模板填充报Create workbook failure

场景 使用 EasyExcel (FastExcel) 做数据导出时&#xff0c;用了通过模板导出数据的形式。 在读取模板文件的时候出现错误导致创建Workbook 失败&#xff0c; 错误日志&#xff1a; Create workbook failure... No valid entries or contents found, this is not a valid OOX…

MongoDB基本操作

一、实验目的 1. 熟悉MongoDB的基本操作&#xff0c;包括CRUD&#xff08;增加、读取、更新、删除&#xff09;。 2. 理解MongoDB的文档型数据库特性和Shell的使用。 3. 培养学生通过命令行操作数据库的能力。 4. 强化数据库操作的实际应用能力。 二、实验环境准备 1.…

基于 WPF 平台使用纯 C# 制作流体动画

一、引言 在 WPF 应用开发中&#xff0c;为界面添加生动的动画效果能显著提升用户体验。通常&#xff0c;我们会结合 XAML 和 C# 来打造各种动画&#xff0c;但今天我们聚焦于如何仅用纯 C# 在 WPF 平台上制作出令人惊艳的流体动画。这不仅能让开发者深入理解 WPF 动画机制&am…