• 项目
    • 2022/11/29
    • 13 个参与者
    反馈

    通过 ASP.NET Core SignalR .NET 客户端库可以从 .NET 应用与 SignalR 中心进行通信。

    查看或下载示例代码如何下载

    本文中的代码示例是使用 .ASP.NET Core SignalR .NET 客户端的 WPF 应用。

    安装 SignalR .NET 客户端包

    Microsoft.AspNetCore.SignalR..NET 客户端需要客户端包才能连接到SignalR中心。

    若要安装该客户端库,请在“包管理器控制台”窗口中运行以下命令:

    PowerShell复制

     
    Install-Package Microsoft.AspNetCore.SignalR.Client

    连接到中心

    若要建立连接,请创建 HubConnectionBuilder 并调用 Build。 在建立连接期间,可以配置中心 URL、协议、传输类型、日志级别、标头和其他选项。 可通过将任何 HubConnectionBuilder 方法插入 Build 中来配置任何必需选项。 使用 StartAsync 启动连接。

    C#复制

     
    using System;
    using System.Threading.Tasks;
    using System.Windows;
    using Microsoft.AspNetCore.SignalR.Client; namespace SignalRChatClient
    {
    public partial class MainWindow : Window
    {
    HubConnection connection;
    public MainWindow()
    {
    InitializeComponent(); connection = new HubConnectionBuilder()
    .WithUrl("http://localhost:53353/ChatHub")
    .Build(); connection.Closed += async (error) =>
    {
    await Task.Delay(new Random().Next(0,5) * 1000);
    await connection.StartAsync();
    };
    } private async void connectButton_Click(object sender, RoutedEventArgs e)
    {
    connection.On<string, string>("ReceiveMessage", (user, message) =>
    {
    this.Dispatcher.Invoke(() =>
    {
    var newMessage = $"{user}: {message}";
    messagesList.Items.Add(newMessage);
    });
    }); try
    {
    await connection.StartAsync();
    messagesList.Items.Add("Connection started");
    connectButton.IsEnabled = false;
    sendButton.IsEnabled = true;
    }
    catch (Exception ex)
    {
    messagesList.Items.Add(ex.Message);
    }
    } private async void sendButton_Click(object sender, RoutedEventArgs e)
    {
    try
    {
    await connection.InvokeAsync("SendMessage",
    userTextBox.Text, messageTextBox.Text);
    }
    catch (Exception ex)
    {
    messagesList.Items.Add(ex.Message);
    }
    }
    }
    }

    处理丢失的连接

    自动重新连接

    可以将 HubConnection 配置为对 HubConnectionBuilder 使用 WithAutomaticReconnect 方法来自动重新连接。 默认情况下,它不会自动重新连接。

    C#复制

     
    HubConnection connection= new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect()
    .Build();

    在没有任何参数的情况下,WithAutomaticReconnect() 将客户端配置为在每次尝试重新连接之前分别等待 0、2、10 和 30 秒,在四次尝试失败后停止。

    在开始任何重新连接尝试之前,HubConnection 会转换为 HubConnectionState.Reconnecting 状态,并触发 Reconnecting 事件。 这样就可警告用户连接已丢失,并提醒其禁用 UI 元素。 非交互式应用可以开始排队或删除消息。

    C#复制

     
    connection.Reconnecting += error =>
    {
    Debug.Assert(connection.State == HubConnectionState.Reconnecting); // Notify users the connection was lost and the client is reconnecting.
    // Start queuing or dropping messages. return Task.CompletedTask;
    };

    如果客户端在其前四次尝试中成功重新连接,则 HubConnection 将转换回 Connected 状态并触发 Reconnected 事件。 这样就可通知用户已重新建立连接并对任何已排队的消息取消排队。

    由于连接对服务器来说是全新的,因此将为 Reconnected 事件处理程序提供一个新的 ConnectionId

    警告

    如果 HubConnection 已配置为跳过协商,则Reconnected 事件处理程序的 connectionId 参数会为 null。

    C#复制

     
    connection.Reconnected += connectionId =>
    {
    Debug.Assert(connection.State == HubConnectionState.Connected); // Notify users the connection was reestablished.
    // Start dequeuing messages queued while reconnecting if any. return Task.CompletedTask;
    };

    WithAutomaticReconnect() 不会将 HubConnection 配置为重试初始启动失败,因此需要手动处理启动失败:

    C#复制

     
    public static async Task<bool> ConnectWithRetryAsync(HubConnection connection, CancellationToken token)
    {
    // Keep trying to until we can start or the token is canceled.
    while (true)
    {
    try
    {
    await connection.StartAsync(token);
    Debug.Assert(connection.State == HubConnectionState.Connected);
    return true;
    }
    catch when (token.IsCancellationRequested)
    {
    return false;
    }
    catch
    {
    // Failed to connect, trying again in 5000 ms.
    Debug.Assert(connection.State == HubConnectionState.Disconnected);
    await Task.Delay(5000);
    }
    }
    }

    如果客户端在其前四次尝试中未成功重新连接,则 HubConnection 将转换为 Disconnected 状态并触发 Closed 事件。 这样就可以尝试手动重启连接或通知用户连接已永久丢失。

    C#复制

     
    connection.Closed += error =>
    {
    Debug.Assert(connection.State == HubConnectionState.Disconnected); // Notify users the connection has been closed or manually try to restart the connection. return Task.CompletedTask;
    };

    若要在断开连接或更改重新连接时间安排之前配置自定义的重新连接尝试次数,WithAutomaticReconnect 会接受一个数字数组,表示在每次开始尝试重新连接之前要等待的延迟(以毫秒为单位)。

    C#复制

     
    HubConnection connection= new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
    .Build(); // .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30) }) yields the default behavior.

    前面的示例将 HubConnection 配置为在连接丢失后立即开始尝试重新连接。 这也适用于默认配置。

    如果第一次重新连接尝试失败,则第二次重新连接尝试还会立即启动,而不是像在默认配置中一样等待 2 秒钟。

    如果第二次重新连接尝试失败,则第三次重新连接尝试将在 10 秒后启动,这与默认配置相同。

    自定义行为再次与默认行为不同,它会在第三次重新连接尝试失败后停止。 在默认配置中,会在接下来 30 秒过后再次尝试重新连接。

    如果想要更好地控制自动重新连接尝试的时间安排和次数,则 WithAutomaticReconnect 需接受实现 IRetryPolicy 接口的对象,该对象具有一个名为 NextRetryDelay 的方法。

    NextRetryDelay 采用一个 RetryContext 类型的参数。 RetryContext 具有三个属性:PreviousRetryCountElapsedTime 和 RetryReason,分别为 long、 TimeSpan 和 Exception。 在尝试第一次重新连接之前,PreviousRetryCount 和 ElapsedTime 将为零,RetryReason 将是导致连接丢失的异常。 在每次重试失败后,PreviousRetryCount 的数量将增加一个,并更新 ElapsedTime 以反映截止目前重新连接所花的时间,RetryReason 将是导致最后一个重新连接尝试失败的异常。

    NextRetryDelay 必须返回表示在下次重新连接尝试之前等待的时间的 TimeSpan,或者在 null 应停止重新连接的情况下返回 HubConnection

    C#复制

     
    public class RandomRetryPolicy : IRetryPolicy
    {
    private readonly Random _random = new Random(); public TimeSpan? NextRetryDelay(RetryContext retryContext)
    {
    // If we've been reconnecting for less than 60 seconds so far,
    // wait between 0 and 10 seconds before the next reconnect attempt.
    if (retryContext.ElapsedTime < TimeSpan.FromSeconds(60))
    {
    return TimeSpan.FromSeconds(_random.NextDouble() * 10);
    }
    else
    {
    // If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
    return null;
    }
    }
    }
    C#复制

     
    HubConnection connection = new HubConnectionBuilder()
    .WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
    .WithAutomaticReconnect(new RandomRetryPolicy())
    .Build();

    或者,你可以编写将手动重新连接客户端的代码,如手动重新连接中所述。

    手动重新连接

    使用 Closed 事件可响应连接丢失。 例如,你可能要自动重新连接。

    Closed 事件需要一个返回 Task 的委托,这使异步代码可在不使用 async void 的情况下运行。 若要在同步运行的 Closed 事件处理程序中满足委托签名,请返回 Task.CompletedTask

    C#复制

     
    connection.Closed += (error) => {
    // Do your close logic.
    return Task.CompletedTask;
    };

    异步支持的主要原因是使你可以重启连接。 启动连接是一种异步操作。

    在重启连接的 Closed 处理程序中,可考虑等待一些随机延迟以防止使服务器过载,如下面的示例中所示:

    C#复制

     
    connection.Closed += async (error) =>
    {
    await Task.Delay(new Random().Next(0,5) * 1000);
    await connection.StartAsync();
    };

    从客户端调用中心方法

    InvokeAsync 会对中心调用方法。 将中心方法中定义的中心方法名称和所有参数传递给 InvokeAsync。 SignalR 是异步的,因此在进行调用时请使用 async 和 await

    C#复制

     
    await connection.InvokeAsync("SendMessage",
    userTextBox.Text, messageTextBox.Text);

    InvokeAsync 方法会返回一个在服务器方法返回时完成的 Task。 返回值(如果有)作为 Task 的结果提供。 服务器上的方法所引发的任何异常都会产生出错的 Task。 使用 await 语法等待服务器方法完成,并使用 try...catch 语法处理错误。

    SendAsync 方法会返回一个在消息已发送到服务器时完成的 Task。 不会提供返回值,因为此 Task 不会等到服务器方法完成。 发送消息期间在客户端上引发的任何异常都会产生出错的 Task。 使用 await 和 try...catch 语法处理发送错误。

    备注

    仅在默认模式下使用 Azure SignalR 服务时,才支持从客户端调用中心方法。 有关详细信息,请参阅常见问题解答(azure-signalr GitHub 存储库)

    从中心调用客户端方法

    在生成之后,但是在启动连接之前使用 connection.On 定义中心调用的方法。

    C#复制

     
    connection.On<string, string>("ReceiveMessage", (user, message) =>
    {
    this.Dispatcher.Invoke(() =>
    {
    var newMessage = $"{user}: {message}";
    messagesList.Items.Add(newMessage);
    });
    });

    connection.On 中的上述代码在服务器端代码使用 SendAsync 方法调用它时运行。

    C#复制

     
    public async Task SendMessage(string user, string message)
    {
    await Clients.All.SendAsync("ReceiveMessage", user,message);
    }

    备注

    虽然连接的中心端支持强类型消息,但客户端必须使用带有方法名称的泛型方法 HubConnection.On 进行注册。 有关示例,请参阅后台服务中的主机 ASP.NET CoreSignalR

    错误处理和日志记录

    使用 try-catch 语句处理错误。 检查 Exception 对象,以确定发生错误后要执行的适当操作。

    C#复制

     
    try
    {
    await connection.InvokeAsync("SendMessage",
    userTextBox.Text, messageTextBox.Text);
    }
    catch (Exception ex)
    {
    messagesList.Items.Add(ex.Message);
    }

    其他资源

     
     

    建议的内容

    • 将 SignalR 用户映射到连接

      本主题演示如何保留有关用户及其连接的信息。 帕特里克·弗莱彻帮助撰写了本主题。 本主题中使用的软件版本...

    • 在 SignalR

      本主题介绍如何使用中心 API 保存组成员身份信息。

    • ASP.NET SignalR 中心 API 指南 - .NET 客户端 (C#)

      本文档介绍在 .NET 客户端中使用适用于 SignalR 版本 2 的中心 API,例如 Windows 应用商店 (WinRT) 、WPF、Silverlight 和 cons...

    • ASP.NET SignalR 中心 API 指南 - 服务器 (C#)

      本文档介绍了如何使用代码示例演示...,介绍 ASP.NET SignalR 中心 API for SignalR 版本 2 的服务器端编程。

    • 管理 SignalR 中的用户和组

      ASP.NET Core SignalR 用户和组管理概述。

    • SignalR 与 ASP.NET Core SignalR 的区别

      SignalR 与 ASP.NET Core SignalR 的区别

    • SignalR 测试和调试

      如何测试和调试 SignalR 应用程序。

    • ASP.NET Core SignalR JavaScript 客户端

      ASP.NET Core SignalR JavaScript 客户端概述。

    显示较少选项
     

ASP.NET Core SignalR .NET 客户端的更多相关文章

  1. ASP.NET Core SignalR中的流式传输

    什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时 ...

  2. Asp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参

    继续学习 最近一直在使用Asp.Net Core SignalR(下面成SignalR Core)为小程序提供websocket支持,前端时间也发了一个学习笔记,在使用过程中稍微看了下它的源码,不得不 ...

  3. Asp.Net Core SignalR 与微信小程序交互笔记

    什么是Asp.Net Core SignalR Asp.Net Core SignalR 是微软开发的一套基于Asp.Net Core的与Web进行实时交互的类库,它使我们的应用能够实时的把数据推送给 ...

  4. [asp.net core]SignalR一个例子

    摘要 在一个后台管理的页面想实时监控一些操作的数据,想到用signalR. 一个例子 asp.net core+signalR 使用Nuget安装包:Microsoft.AspNetCore.Sign ...

  5. ASP.NET Core SignalR

    ASP.NET Core SignalR 是微软开发的一套基于ASP.NET Core的与Web进行实时交互的类库,它使我们的应用能够实时的把数据推送给Web客户端. 功能 自动管理连接 允许同时广播 ...

  6. ASP.NET Core SignalR:基础概述

    一.简介 ASP.NET Core SignalR 是一个开源代码库,它简化了向应用添加实时 Web 功能的过程. 实时 Web 功能使服务器端代码能够即时将内容推送到客户端. SignalR 的适用 ...

  7. ASP.NET Core SignalR 使用

    SignalR: 实时 Web 功能使服务器端代码能够即时将内容推送到客户端(包括B/S,C/S,Andriod).   SignalR最新版本为3.0(截止2020-02-28)   SignalR ...

  8. ASP.NET CORE使用WebUploader对大文件分片上传,并通过ASP.NET CORE SignalR实时反馈后台处理进度给前端展示

    本次,我们来实现一个单个大文件上传,并且把后台对上传文件的处理进度通过ASP.NET CORE SignalR反馈给前端展示,比如上传一个大的zip压缩包文件,后台进行解压缩,并且对压缩包中的文件进行 ...

  9. ASP.NET Core 使用 Redis 客户端

    Mac OS 安装 Redis(用于连 Redis 服务器,方便查看数据):https://redis.io/topics/quickstart wget http://download.redis. ...

  10. 使用websocket连接(对接)asp.net core signalr

    使用通用websocket连接asp.net core signalr 一.背景介绍 signalr的功能很强大,可以为我们实现websocket服务端节省不少的时间.但是可能由于不同的环境,我们在对 ...

随机推荐

  1. 重新整理 .net core 实践篇—————应用分层[二十四]

    前言 简单整理一下分层. 正文 应用程序分层,分为: 1.领域模型层 2.基础设施层 3.应用层 4.共享层 共享层 共享层一般包括下面几个类库. 有一个Core 的类库,比如说BLog.Core. ...

  2. formdata 的前世今生

    前言 为什么会产生formdata这东西呢? 看下简介: FormData 接口提供了一种表示表单数据的键值对的构造方式,经过它的数据可以使用 XMLHttpRequest.send() 方法送出,本 ...

  3. leetcode:1380. 矩阵中的幸运数

    1380. 矩阵中的幸运数 给你一个 m * n 的矩阵,矩阵中的数字 各不相同 .请你按 任意 顺序返回矩阵中的所有幸运数. 幸运数是指矩阵中满足同时下列两个条件的元素: 在同一行的所有元素中最小 ...

  4. Oracle 在PL/SQL将字符串分割输出

    Oracle 在PL/SQL将字符串分割输出 示例如下: declare begin for maina in (select tt.line ll from (select regexp_subst ...

  5. App隐私合规“免费”自动化检测

    简介: App隐私合规检测提供了全面的隐私合规检测报告和专家建议,从确保形式合规(隐私政策文本合规性)及实质合规(代码层合规性)的一致性,从个人信息收集.权限使用场景.超范围采集.隐私政策.三方SDK ...

  6. 云钉一体:EventBridge 联合钉钉连接器打通云钉生态

    ​简介:今天,EventBridge 联合钉钉连接器,打通了钉钉生态和阿里云生态,钉钉的生态伙伴可以通过通道的能力驱动阿里云上海量的计算力. 作者:尘央 背景 "以事件集成阿里云,从 Eve ...

  7. KubeVela:标准化的云原生平台构建引擎

    简介: 本文由"GO 开源说"第三期 KubeVela 直播内容修改整理而成,视频内容较长,本文内容有所删减和重构. KubeVela 的背景 KubeVela 是一个基于 Go ...

  8. 在阿里巴巴,我们如何先于用户发现和定位 Kubernetes 集群问题?

    ​简介:本文整理自阿里云高级研发工程师彭南光(光南) 在 KubeCon China 2021 大会的演讲实录,分享了阿里巴巴是如何通过自研通用链路探测+定向巡检工具 KubeProbe 应对大规模集 ...

  9. Flink + Iceberg + 对象存储,构建数据湖方案

    ​简介: 上海站 Flink Meetup 分享内容,如何基于Flink.对象存储.Iceberg 来构建数据湖生态. 本文整理自 Dell 科技集团高级软件研发经理孙伟在 4 月 17 日 上海站 ...

  10. 获国际架构顶会ATC2021最佳论文!Fuxi2.0去中心化的调度架构详解

    简介: 近日,在国际体系架构顶会USENIX ATC2021上,阿里云飞天伏羲团队与香港中文大学合作的一篇论文<Scaling Large Production Clusters with Pa ...