开发者

C# 中 WebSocket 与 SignalR实时通信的两种方案

开发者 https://www.devze.com 2025-05-10 11:29 出处:网络 作者: 吴五万
目录一、什么是 WebSocket?WebSocket 特点:使用场景:二、什么是 SignalR?SignalR 特点:使用场景:三、WebSocket vs SignalR 对比四、示例代码示例 1:WebSocket 服务端 + 客户端(.NET)服务端(控制台程序)客
目录
  • 一、什么是 WebSocket?
    • WebSocket 特点:
    • 使用场景:
  • 二、什么是 SignalR?
    • SignalR 特点:
    • 使用场景:
  • 三、WebSocket vs SignalR 对比
    • 四、示例代码
      • 示例 1:WebSocket 服务端 + 客户端(.NET)
      • 服务端(控制台程序)
      • 客户端(JavaScript)
      • 示例 2:SignalR 服务端 + 客户端(ASP.NET Core)
        • 服务端(Startup.cs 或 Program.cs)
        • 客户端(javascript)
    • 五、总结
      • 六、延伸阅读

        在现代 Web 应用中,实时通信变得越来越重要。无论是聊天应用、在线游戏、股票行情推送还是协作编辑工具,都需要服务器能够主动向客户端推送数据。在 .NET 生态系统中,WebSocket 和 SignalR 是实现这一功能的两个主要方案。

        本文将对这两种技术进行比较,分析它们的异同点和使用场景,并提供简单示例代码帮助你快速上手。

        一、什么是 WebSocket?

        WebSocket 是 html5 提供的一种全双工通信协议,允许客户端与服务器之间建立持久连接,实现双向实时通信。相比传统的 HTTP 请求-响应模式,WebSocket 更加高效,适合需要频繁交互的应用。

        WebSocket 特点:

        • 基于 TCP 协议
        • 支持双向通信
        • 连接是长连接(保持打开)
        • 轻量级,性能高
        • 需要手动管理连接和消息处理

        使用场景:

        • 实时数据推送(如股票行情)
        • 在线多人游戏
        • 多人协作编辑
        • IoT 设备通信等

        二、什么是 SignalR?

        SignalR 是微软开发的一个基于 .NET 的库,它简化了实时通信的实现。SignalR 内部封装了多种传输方式(包括 WebSocket、Server-Sent Events、长轮询等),并根据浏览器和网络环境自动选择最优的方式。

        SignalR 特点:

        • 抽象了底层通信细节
        • 支持跨平台(.NET Core / .NET 6+)
        • 自动降级兼容性差的浏览器
        • 提供 Hub 模式,易于组织业务逻辑
        • 可集成到 ASP.NET Core 中

        使用场景:

        • 快速构建实时功能(无需关注底层通信细节)
        • Web 应用中的通知系统
        • 即时通讯(IM)应用
        • 实时仪表盘、状态监控

        三、WebSocket vs SignalR 对比

        特性WebSocketSignalR
        通信方式全双工全双工(通过封装)
        是否需要手动处理连接✅ 需要❌ 不需要
        是否支持多路复用❌ 不支持✅ 支持(Hub)
        是否支持自动降级❌ 不支持✅ 支持(长轮询等)
        开发复杂度较高较低
        性能略低于 WebSocket
        适合场景高性能、定制化通信快速开发、通用实时功能

        四、示例代码

        示例 1:WebSocket 服务端 + 客户端(.编程客栈NET)

        服务端(控制台程序)

        using System;
        using System.Net;
        using System.Net.WebSockets;
        using System.Text;
        using System.Threading;
        using System.Threading.Tasks;
        class Program
        {
            static async Task Main(string[] args)
            {
                HttpListener listener = new HttpListener();
                lpythonistener.Prefixes.Add("http://localhost:5000/");
                listener.Start();
                Console.WriteLine("WebSocket Server started on http://localhost:5000");
                while (true)
                {
                    HttpListenaKGNfpgVwperContext context = await listener.GetContextAsync();
                    if (context.Request.IsWebSocketRequest)
                    {
                        WejavascriptbSocketContext webSocketContext = await context.AcceptWebSocketAsync(null);
                        _ = HandleWebSocketConnection(webSocketContext.WebSocket);
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                        context.Response.Close();
                    }
                }
            }
            private static async Task HandleWebSocketConnection(WebSocket socket)
            {
                byte[] buffer = new byte[1024 * 4];
                while (socket.State == WebSocketState.Open)
                {
                    WebSocketReceiveResult result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    Console.WriteLine($"Received: {message}");
                    // Echo back the message
                    byte[] response = Encoding.UTF8.GetBytes($"Echo: {message}");
                    await socket.SendAsync(new ArraySegment<byte>(response), WebSocketMessageType.Text, true, CancellationToken.None);
                }
            }
        }

        客户端(JavaScript)

        <!DOCTYPE html>
        <html>
        <head>
            <title>WebSocket Client</title>
        </head>
        <body>
            <input type="text" id="messageInput" placeholder="Enter message" />
            <button onclick="sendMessage()">Send</button>
            <div id="output"></div>
            <script>
                const ws = new WebSocket('ws://localhost:5000');
                ws.onmessage = function (event) {
                    document.getElementById('output').innerText += event.data + '\n';
                };
                function sendMessage() {
                    const input = document.getElementById('messageInput');
                    const message = input.value;
                    ws.send(message);
                    input.value = '';
                }
            </script>
        </body>
        </html>

        示例 2:SignalR 服务端 + 客户端(ASP.NET Core)

        服务端(Startup.cs 或 Program.cs)

        var builder = WebApplication.CreateBuilder(args);
        // Add services to the container.
        builder.Services.AddSignalR();
        var app = builder.Build();
        app.MapHub<ChatHub>("/chatHub");
        app.Run();
        public class ChatHub : Hub
        {
            public async Task Send(string user, string message)
            {
                await Clients.All.SendAsync("ReceiveMessage", user, message);
            }
        }

        客户端(JavaScript)

        <script src="https://cdnjs.cloudflare.com/AJAX/libs/microsoft-signalr/5.0.13/signalr.min.js"></script>
        <input type="text" id="userInput" placeholder="User" />
        <input type="text" id="messageInput" placeholder="Message" />
        <button onclick="sendMessage()">Send</button>
        <div id="chat"></div>
        <script>
            const connection = new signalR.HubConnectionBuilder()
                .withUrl("/chatHub")
                .build();
            connection.on("ReceiveMessage", function (user, message) {
                const msg = `${user}: ${message}`;
                document.getElementById("chat").innerHTML += `<p>${msg}</p>`;
            });
            connection.start().catch(function (err) {
                return console.error(err.toString());
            });
            function sendMessage() {
                const user = document.getElementById("userInput").value;
                const message = document.getElementById("messageInput").value;
                connection.invoke("Send", user, message).catch(function (err) {
                    return console.error(err.toString());
                });
                document.getElementById("messageInput").value = "";
            }
        </script>

        五、总结

        场景推荐技术
        高性能、低延迟、自定义协议WebSocket
        快速开发、通用实时功能SignalR
        浏览器兼容性要求高SignalR
        需要精细控制通信过程WebSocket

        如果你正在开发一个简单的聊天室或通知系统,SignalR 是更好的选择;而如果你需要构建一个高性能、低延迟的物联网通信系统,WebSocket 更合适

        六、延伸阅读

        • Microsoft SignalR 文档
        • WebSocket W3C 标准文档
        • ASP.NET Co编程客栈re WebSocket 支持

        到此这篇关于C# 中 WebSocket 与 SignalR:实时通信的两种选择的文章就介绍到这了,更多相关C# WebSocket 与 SignalR实时通信内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        关注公众号