展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > C# SignalR实时通信实现方法

C# SignalR实时通信实现方法

SignalR实现实时通信的核心是通过Hub抽象层自动选择最佳传输协议(如WebSocket、SSE或LongPolling)并处理连接管理与消息传递。1.创建继承Hub的类定义服务器端方法;2.在Program.cs中注册SignalR服务并映射Hub路由;3.客户端通过SignalR库连接Hub,使用connection.invoke调用服务器方法,通过connection.on接收服务器推送;4.SignalR根据环境自动协商和降级传输协议以确保兼容性;5.认证通过ASP.NETCore认证机制集成

本文目录

    SignalR实现实时通信的核心是通过Hub抽象层自动选择最佳传输协议(如WebSocket、SSE或Long Polling)并处理连接管理与消息传递。1. 创建继承Hub的类定义服务器端方法;2. 在Program.cs中注册SignalR服务并映射Hub路由;3. 客户端通过SignalR库连接Hub,使用connection.invoke调用服务器方法,通过connection.on接收服务器推送;4. SignalR根据环境自动协商和降级传输协议以确保兼容性;5. 认证通过ASP.NET Core认证机制集成,客户端可携带JWT或Cookie,服务器端使用[Authorize]属性控制访问权限;6. 高并发下可通过Azure SignalR Service或Redis Backplane实现横向扩展,结合分组、定向发送、消息节流等策略优化性能,确保系统可伸缩与高效。

    C#的SignalR如何实现实时通信?

    C#的SignalR实现实时通信,核心在于它提供了一个抽象层,让开发者可以轻松地在服务器和客户端之间建立持久的双向连接。它内部会根据环境自动选择最佳的传输方式,比如WebSocket,如果不支持就降级到Server-Sent Events或Long Polling,从而确保消息能够即时地从服务器推送到客户端,反之亦然,而不需要客户端不断地发起请求。

    解决方案

    SignalR的实时通信能力,说到底,就是它提供了一套优雅的API和运行时机制,让我们能像调用本地方法一样,在服务器端调用客户端的方法,或者在客户端调用服务器端的方法。这背后,SignalR处理了所有复杂的连接管理、消息序列化、传输协议选择以及错误恢复等细节。

    核心组件:Hubs

    SignalR的核心抽象是Hub(集线器)。你可以把它想象成一个通信的中心,客户端连接到Hub,通过Hub发送和接收消息。

    1. 创建Hub: 在ASP.NET Core项目中,你需要创建一个继承自Microsoft.AspNetCore.SignalR.Hub的类。这个类里可以定义公共方法,这些方法就是客户端可以调用的服务器端方法。

      // Server-side: MyChatHub.cs
      using Microsoft.AspNetCore.SignalR;
      using System.Threading.Tasks;
      
      public class MyChatHub : Hub
      {
          public async Task SendMessage(string user, string message)
          {
              // 调用所有连接到这个Hub的客户端上的 "ReceiveMessage" 方法
              await Clients.All.SendAsync("ReceiveMessage", user, message);
          }
      
          public override async Task OnConnectedAsync()
          {
              // 当有新客户端连接时触发
              Console.WriteLine($"Client connected: {Context.ConnectionId}");
              await base.OnConnectedAsync();
          }
      
          public override async Task OnDisconnectedAsync(Exception exception)
          {
              // 当客户端断开连接时触发
              Console.WriteLine($"Client disconnected: {Context.ConnectionId}");
              await base.OnDisconnectedAsync(exception);
          }
      }
    2. 配置SignalR: 在ASP.NET Core的Startup.cs(或Program.cs)中,你需要注册SignalR服务并映射Hub的路由。

      // Program.cs (Minimal API style)
      var builder = WebApplication.CreateBuilder(args);
      
      builder.Services.AddSignalR(); // 注册SignalR服务
      
      var app = builder.Build();
      
      app.MapHub("/chatHub"); // 映射Hub的路由
      
      app.Run();

    客户端交互

    客户端(可以是JavaScript、.NET、Java、Swift等)通过SignalR客户端库连接到Hub。

    1. JavaScript客户端示例: 在前端页面中,引入SignalR客户端库,然后建立连接并定义消息处理逻辑。

      // Client-side: index.html 或 JavaScript 文件
      const connection = new signalR.HubConnectionBuilder()
          .withUrl("/chatHub") // 连接到服务器上的Hub路由
          .withAutomaticReconnect() // 自动重连,挺重要的,尤其网络不稳时
          .build();
      
      // 监听服务器调用客户端的 "ReceiveMessage" 方法
      connection.on("ReceiveMessage", (user, message) => {
          const li = document.createElement("li");
          li.textContent = `${user}: ${message}`;
          document.getElementById("messagesList").appendChild(li);
      });
      
      // 连接到Hub
      connection.start()
          .then(() => console.log("SignalR Connected!"))
          .catch(err => console.error("SignalR Connection Error: ", err));
      
      // 客户端调用服务器的 "SendMessage" 方法
      document.getElementById("sendButton").addEventListener("click", () => {
          const user = document.getElementById("userInput").value;
          const message = document.getElementById("messageInput").value;
          connection.invoke("SendMessage", user, message) // 调用服务器上的 SendMessage 方法
              .catch(err => console.error("Error sending message: ", err));
      });

    通过这种方式,服务器可以主动向客户端推送消息(Clients.All.SendAsync),客户端也可以主动调用服务器上的方法(connection.invoke),实现了真正的双向实时通信。

    SignalR支持哪些传输协议?它们是如何工作的?

    SignalR为了确保在各种网络环境下都能实现实时通信,它支持多种传输协议,并且会智能地进行协商和降级。这背后的逻辑其实挺有意思的,它不是盲目选择,而是尝试用最好的,不行就退而求其次。

    主要的传输协议有:

    1. WebSockets: 这是SignalR首选的传输协议。WebSocket提供了一个真正的全双工通信通道,一旦连接建立,服务器和客户端可以随时互相发送消息,效率最高,延迟最低。它就像在浏览器和服务器之间打通了一条专用电话线,随时都能通话。
    2. Server-Sent Events (SSE): 如果客户端或服务器不支持WebSocket,SignalR会尝试使用SSE。SSE是一种单向协议,服务器可以持续地向客户端发送数据,但客户端不能通过同一个连接向服务器发送数据。客户端向服务器发送数据时,需要使用传统的HTTP请求。你可以把它想象成服务器在广播电台,客户端只能收听。
    3. Long Polling: 这是SignalR的最终降级方案,也是兼容性最好的。客户端会向服务器发起一个HTTP请求,服务器会保持这个请求打开,直到有新的数据可用或者达到超时时间。一旦有数据,服务器就响应并关闭连接。客户端收到数据后,会立即发起一个新的请求。这就像客户端不停地问“有新邮件吗?”,服务器有就给,没有就让它等等。

    工作原理:协商过程

    当SignalR客户端尝试连接到服务器时,它会首先发起一个“协商”请求(negotiate)。服务器会返回一个包含可用传输协议列表以及其他连接信息的响应。客户端会根据这个列表和自身能力,选择最佳的传输协议。通常,如果WebSocket可用且被支持,它会是首选。如果WebSocket连接失败或不可用,SignalR客户端会按照优先级顺序(WebSocket -> SSE -> Long Polling)尝试其他协议,直到找到一个可用的。这个过程对开发者来说是透明的,我们通常不需要关心具体使用了哪种协议,SignalR会自动搞定。

    在SignalR中如何处理用户认证和授权?

    在实时应用中,确保只有经过身份验证的用户才能连接到特定的Hub,并且只有授权的用户才能调用特定的方法,这绝对是安全性的核心。SignalR在这方面与ASP.NET Core的认证授权机制结合得相当紧密,用起来也挺顺手的。

    1. 集成认证: SignalR Hubs 可以直接利用ASP.NET Core的现有认证管道。这意味着,如果你的应用程序已经配置了基于Cookie、JWT Bearer Token或其他任何认证方案,SignalR Hubs 会自动识别当前连接的用户身份。

      • Cookie认证: 如果你的Web应用使用Cookie认证,用户登录后,浏览器会自动在SignalR连接请求中携带认证Cookie。SignalR Hub会读取这个Cookie来识别用户。

      • JWT Bearer Token认证: 对于API或SPA应用,客户端在建立SignalR连接时,通常会在URL查询字符串或HTTP请求头中附带JWT Token。

        // JavaScript 客户端附带JWT Token
        const connection = new signalR.HubConnectionBuilder()
            .withUrl("/chatHub", {
                accessTokenFactory: () => "你的JWT Token" // 这里传入你的JWT
            })
            .build();

        服务器端需要配置JWT认证中间件:

        // Program.cs
        builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options => { /* 配置JWT验证参数 */ });
        builder.Services.AddAuthorization(); // 别忘了添加授权服务
    2. 应用授权: 一旦用户身份被认证,你就可以使用ASP.NET Core的[Authorize]属性来控制对Hub或Hub方法的访问。

      • 授权整个Hub: 如果你想让整个Hub只能被已认证用户访问,直接在Hub类上加上[Authorize]属性。

        // Server-side: MyChatHub.cs
        using Microsoft.AspNetCore.Authorization; // 引入命名空间
        
        [Authorize] // 只有已认证的用户才能连接到这个Hub
        public class MyChatHub : Hub
        {
            public async Task SendMessage(string user, string message)
            {
                // ...
            }
        }
      • 授权特定的Hub方法: 你也可以只保护Hub中的某些方法,让其他方法可以被匿名访问。

        public class MyChatHub : Hub
        {
            // 这个方法所有人都可以调用
            public async Task GetPublicMessage() { /* ... */ }
        
            [Authorize] // 只有已认证的用户才能调用这个方法
            public async Task SendPrivateMessage(string recipientId, string message)
            {
                // ...
            }
        
            [Authorize(Roles = "Admin")] // 只有角色为 "Admin" 的用户才能调用
            public async Task BanUser(string userId)
            {
                // ...
            }
        }
    3. 在Hub中访问用户身份: 在Hub方法内部,你可以通过Context.User属性访问当前连接用户的ClaimsPrincipal对象,从而获取用户的ID、角色、声明等信息。这对于根据用户身份发送特定消息或执行特定逻辑非常有用。

      [Authorize]
      public class MyChatHub : Hub
      {
          public async Task SendMessageToMe(string message)
          {
              var userId = Context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value; // 获取用户ID
              if (!string.IsNullOrEmpty(userId))
              {
                  await Clients.User(userId).SendAsync("ReceiveMyMessage", message);
              }
          }
      }

      这样,你就能非常灵活地控制谁能连接、谁能发送什么、谁能接收什么,让你的实时应用既强大又安全。

    SignalR在高并发场景下有哪些挑战和优化策略?

    SignalR在处理高并发连接和大量消息时,确实会遇到一些挑战,但幸运的是,社区和微软都提供了成熟的解决方案。我个人觉得,理解这些挑战的本质,比单纯记住解决方案更重要,因为它能帮你更好地设计系统。

    主要挑战:

    1. 单服务器瓶颈: 单个SignalR服务器的连接数是有限的,受限于服务器的CPU、内存和网络I/O。当连接数达到一定规模(比如几千到几万)时,单台服务器可能就扛不住了,特别是广播消息时,服务器需要向每个连接发送一份数据。
    2. 状态管理: 如果你的Hub需要维护一些状态(比如在线用户列表、房间信息),在多服务器环境下,这些状态同步会变得复杂。
    3. 消息传递效率: 大量消息的频繁发送,尤其是在广播给所有连接时,会消耗大量带宽和服务器资源。
    4. 连接断开与重连: 客户端网络不稳定或服务器重启时,连接会断开。SignalR虽然有自动重连机制,但如果断开过于频繁,会增加服务器负担,影响用户体验。

    优化策略:

    1. 横向扩展(Scale Out):使用Backplane 这是解决单服务器瓶颈最核心的策略。当你有多个SignalR服务器实例时,它们需要一种方式来互相通信,以便当一个服务器收到消息时,能够通知其他服务器将消息广播给它们所连接的客户端。这个机制就是“Backplane”(回板)。

      • Azure SignalR Service: 如果你在Azure上部署,这是最简单、最推荐的方案。它是一个全托管的服务,为你处理所有的连接管理、扩展性和Backplane问题。你只需要把你的SignalR Hub指向这个服务,剩下的它就帮你搞定了。这省去了很多运维的麻烦。
      • Redis Backplane: 对于自托管或混合云环境,Redis是一个非常流行的选择。SignalR服务器实例都连接到同一个Redis实例,当一个服务器要发送消息时,它会将消息发布到Redis的某个通道,其他服务器订阅这个通道,从而接收到消息并转发给它们各自的客户端。这需要你自己管理Redis实例。
      • SQL Server Backplane: 早期版本也有SQL Server Backplane,但性能通常不如Redis,现在推荐使用Redis或Azure SignalR Service。

      使用Backplane后,每个SignalR服务器实例只需要处理它自己那一小部分连接,而消息的全局广播则通过Backplane协调,大大提升了整体吞吐量。

    2. 优化消息传递:

      • 定向发送: 尽量避免无差别的Clients.All.SendAsync()。如果消息只针对特定用户、特定组或特定连接,就使用Clients.User(), Clients.Group(), Clients.Client()等方法。这能显著减少不必要的网络流量和服务器处理。
      • 消息分组: 利用Groups.AddToGroupAsync()和Groups.RemoveFromGroupAsync()将相关用户分组。这样,你可以一次性向一个组发送消息,而不是遍历所有用户。比如,聊天室应用可以把每个房间的用户放进一个组。
      • 减少消息大小: 避免在实时消息中传输大量冗余数据。只发送必要的信息,或者发送一个ID,让客户端根据ID去请求完整数据。
      • 限制消息频率: 对于高频更新的场景(比如股票报价),可以考虑在服务器端进行消息聚合或节流,避免每秒发送数百条细粒度消息。
    3. 客户端优化:

      • 自动重连: 确保客户端启用了withAutomaticReconnect(),这能有效应对短暂的网络波动,减少用户感知到的断开。
      • UI更新优化: 在客户端,对于高频数据更新,使用节流(throttle)或防抖(debounce)技术来更新UI,避免频繁DOM操作导致性能问题。
      • 连接管理: 在不再需要实时通信时,及时关闭客户端连接,释放服务器资源。
    4. 负载均衡器配置: 如果你在使用多个SignalR服务器实例并且没有使用Backplane(这种情况很少见,但比如在测试环境),或者你的Backplane是Redis,那么负载均衡器需要配置为“粘性会话”(Sticky Sessions)。这意味着同一个客户端的请求总是被路由到同一个SignalR服务器实例。这是因为SignalR的连接是持久的,客户端和服务器之间需要维持状态。不过,如果使用了Azure SignalR Service或Redis Backplane,通常就不需要粘性会话了,因为Backplane已经解决了跨服务器的消息同步问题。

    总之,SignalR在高并发下的关键在于“分而治之”和“减少浪费”。通过横向扩展和智能地发送消息,可以构建出非常健壮和高性能的实时应用。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。