ASP .NET CORE 6 项目实现WebSocket通信实践

一、简介

WebSocket 是一种计算机通信协议,提供了全双工通信通道,特别适用于需要频繁更新数据的应用,如实时聊天、在线游戏和股票行情等。它在 Web 应用中有着广泛的应用,因为它能够在客户端和服务器之间建立持久连接,从而实现低延迟、高效的数据传输。

二、WebSocket 原理

  1. 握手过程:

    • 客户端发起 HTTP 请求,通过 Upgrade 头部字段请求升级到 WebSocket 协议。
    • 服务器接收到请求后,如果支持 WebSocket,则返回一个 101 状态码响应,表示协议切换成功。
  2. 建立连接:

    • 握手成功后,客户端和服务器之间建立了一条持久连接,可以通过这个连接进行双向通信。
  3. 数据传输:

    • 数据以帧(frame)的形式传输,每个帧包含一个固定的头部和可变长度的数据部分。
    • 帧可以是文本帧、二进制帧、关闭帧、Ping 帧或 Pong 帧。
  4. 关闭连接:

    • 任一方都可以发送关闭帧来终止连接,另一方接收到关闭帧后也会发送一个关闭帧作为响应,然后连接关闭。

三、WebSocket 的作用

  1. 实时通信:

    • WebSocket 提供了低延迟的双向通信,非常适合实时应用,如在线聊天、协作编辑和多人游戏等。
  2. 减少网络开销:

    • 与传统的轮询方式相比,WebSocket 减少了不必要的 HTTP 请求和响应,从而降低了网络开销和服务器负载。
  3. 高效的数据传输:

    • WebSocket 使用较小的头部信息,并且在连接建立后无需重复握手过程,使得数据传输更加高效。
  4. 保持长连接:

    • 一旦建立连接,客户端和服务器之间可以持续通信,不需要频繁重新建立连接。
  5. 跨平台支持:

    • WebSocket 被广泛支持,包括现代浏览器、移动设备和各种服务器框架,使其成为构建跨平台实时应用的理想选择。

四、项目实践

1、新建WEB API 项目
2、新增WebStock拦截中间件:WebSocketMiddleware.cs
cs 复制代码
public class WebSocketMiddleware
{
    private readonly RequestDelegate _requestDelegate;
    public WebSocketMiddleware(RequestDelegate requestDelegate)
    {
        _requestDelegate=requestDelegate;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Path == "/ws" && context.WebSockets.IsWebSocketRequest == true) 
        { 
            using(var webSocket = await context.WebSockets.AcceptWebSocketAsync())
            {
                await Echo(webSocket);
            }
        }
        else
        {
            await _requestDelegate(context);
        }
    }
    private async Task Echo(WebSocket webSocket)
    {
        //封装数组片段:ArraySegment<T> 封装了一个数组及其指定的范围(起始索引和长度),使得可以对数组的某一部分进行操作,而不需要复制数组
        var buffer = new byte[1024 * 4];
        WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        while(!result.CloseStatus.HasValue)
        {              
            var receivedMessage = Encoding.UTF8.GetString(buffer);
            Console.WriteLine(receivedMessage);
            //回显:在网络通信中,"Echo" 表示将接收到的数据原样返回给发送方
            var responseMessage = $"Echo:{receivedMessage}";
            var bytesToSend = Encoding.UTF8.GetBytes(responseMessage);
            await webSocket.SendAsync(new ArraySegment<byte>(bytesToSend),result.MessageType,result.EndOfMessage,CancellationToken.None);
            result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        }            
        await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);        
    }      
}
3、Program程序入口注册使用WebStock中间件:
cs 复制代码
//添加WebSocket支持
app.UseWebSockets();
app.UseMiddleware<WebSocketMiddleware>();
4、新建WebStock控制器,用于测试WebStock通信:
cs 复制代码
public class WebSocketController : ControllerBase
{
    // GET: api/<WebSocketController>
    [HttpGet("Requset")]
    public async Task<IActionResult> Resquest()
    {
        //using MiniProfiler.Current.Step("Web Stock request");
        using (MiniProfiler.Current.Step("Web Stock request"))
        using (ClientWebSocket webSocket = new ClientWebSocket())
        {
            Uri uri = new Uri("ws://localhost:8084/ws");
            //创建连接
            await webSocket.ConnectAsync(uri, CancellationToken.None);
            Console.WriteLine("webSocker Connect Successfully!");

            //发送消息
            string sendMessage = "你好,我是WebSocket请求者!";
            var bytes = Encoding.UTF8.GetBytes(sendMessage);
            await webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None);
            Console.WriteLine($"Send:{sendMessage}");

            //接收消息
            byte[] buffer = new byte[1024 * 4];
            await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            var receiveMessage = Encoding.UTF8.GetString(buffer);
            Console.WriteLine($"Receive:{receiveMessage}");

            //关闭连接
            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
            Console.WriteLine("webSocket Close Successfully");
        }
        return Ok();
    }
5、测试

启动api,开启Swagger支持,使用Swagger对WebStock通信发起请求,查看控制台输出。

五、总结

总之,WebSocket 通过提供高效、低延迟的双向通信机制,极大地提升了 Web 应用的实时性能和用户体验。

相关推荐
吃一碗粉只付一碗钱5 小时前
12-给SPA友好的401和403响应
c#·状态模式
2301_780789665 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
2501_915106326 小时前
抓包抓到乱码或压缩字节怎么解析,TraceEagle五种查看模式和一键解码
网络协议·计算机网络·网络安全·ios·adb·https·udp
情 九6 小时前
MCP 实战 06:把 HTTP 接口接成工具,让 AI 帮你查数据
人工智能·网络协议·http·mcp
星融元asterfusion7 小时前
工业网络升级实战:100G 双轨 Leaf-Spine 架构破解高并发出货网络瓶颈
网络·架构·spine
Da Da 泓7 小时前
五子棋 Web 端测试用例报告
前端·网络·websocket·网络协议·测试用例·项目
云和数据.ChenGuang8 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
ESDWAN9 小时前
企业网络监控应该监测哪些目标?网关、网络节点还是业务系统?
服务器·网络·php
mennekes9 小时前
临时用电线路标识:插头颜色、钟面标识配套规范
运维·网络·科技·安全·制造
发光小北10 小时前
EtherNet/IP 转 ModbusTCP 网关现场应用中会遇到什么问题?
服务器·网络·tcp/ip