在正常运行时间较长后,服务器端 SignalR 连接失败

2024-05-15

我在 StackOverflow 上搜索了许多与 SignalR 连接相关的其他问题,但似乎都不适用于我的具体情况。

我有一个使用 SignalR 集线器的应用程序。客户端可以使用两种方法连接到集线器:

  1. 通过使用底层客户端连接到集线器的.NET Core API
  2. 直接连接到中心的 URL

我遇到的问题是使用 .NET Core API(方法 1)进行连接。当服务器端应用程序运行很长一段时间(可能是 2 周)时,API 使用的 SignalR 连接会失败。与 SignalR 集线器的直接连接(方法 2)仍然有效。

以下是通过 API 进行连接的方式:

.NET Core Web API

[Route("~/api/heartbeat")]
[HttpPost]
public async Task SendHeartbeat(nodeId) {
    await SignalRClient.SendHeartbeat(nodeId);
    ...
}

SignalR 客户端

public static class SignalRClient
{

    private static HubConnection _hubConnection;

    /// <summary>
    /// Static SignalRHub client - to ensure that a single connection to the SignalRHub is re-used,
    /// and to prevent excessive connections that cause SignalR to fail
    /// </summary>
    static SignalRClient()
    {
        string signalRHubUrl = "...someUrl";

        _hubConnection = new HubConnectionBuilder()
        .WithUrl(signalRHubUrl)
        .Build();

        _hubConnection.Closed += async (error) =>
        {
            Log.Error("SignalR hub connection was closed - reconnecting. Error message - " + error.Message);

            await Task.Delay(new Random().Next(0, 5) * 1000);
            try
            {
                Log.Error("About to reconnect");
                await _hubConnection.StartAsync();
                Log.Error("Reconnect now requested");
            }
            catch (Exception ex)
            {
                Log.Error("Failed to restart connection to SignalR hub, following a disconnection: " + ex.Message);
            }
        };

        InitializeConnection();
    }

    private static async void InitializeConnection()
    {
        try
        {
            Log.Information("Checking hub connection status");
            if (_hubConnection.State == HubConnectionState.Disconnected)
            {
                Log.Information($"Starting SignalRClient using signalRHubUrl");
                await _hubConnection.StartAsync();
                Log.Information("SignalRClient started successfully");
            }
        }
        catch (Exception ex)
        {
            Log.Error("Failed to start connection to SignalRClient : " + ex.Message + ", " + ex.InnerException.Message);
        }
    }

    public static async Task SendHeartbeat(string nodeId)
    {
        try
        {
            Log.Information("Attempting to send heartbeat to SignalRHub");
            await _hubConnection.InvokeAsync("SendNodeHeartbeatToMonitors", nodeId);
        }
        catch (Exception ex)
        {
            Log.Error($"Error when sending heartbeat to SignalRClient  for NodeId: {nodeId}. Error: {ex.Message}");
        }
    }

正常运行大约 2 周后,连接失败并且doesn't恢复后,我可以在日志中看到错误:

Error when sending transaction to SignalRClient from /api/heartbeat: The 'InvokeCoreAsync' method cannot be called if the connection is not active

我不明白这是怎么发生的,因为我正在使用_hubConnection.Closed方法中的SignalRClient处理连接关闭时的情况,然后执行await _hubConnection.StartAsync();重新启动连接,如上面的代码所示。

连接是经常由于某种原因关闭(每 30 分钟),但它通常会恢复连接,并且我在日志中看到以下错误:

SignalR hub connection was closed - reconnecting. Error message - The remote party closed the WebSocket connection without completing the close handshake.

这说明代码已经成功进入_hubConnection.Closed方法(因为这是我记录该消息的地方),因此看起来连接通常会成功重新启动。

那么,为什么有时连接完全失败却无法重新启动呢?我想知道我是否以合理的方式连接到 SignalR 集线器(特别是,我想知道是否使用静态类SignalRClient是一个很好的模式)。我想知道我的实际问题是否是所有这些The remote party closed the WebSocket connection without completing the close handshake.错误?如果是这样的话,可能是什么原因造成的?

非常感谢任何为我指明正确方向的建议。


几年前我遇到了同样的问题,当时我通过将对 StartAsync 的所有调用放在自己的任务中来解决这个问题。虽然我对此可能是错误的,但我自己的实验表明 HubConnection 本身不可重用,因此在断开连接后也需要重新创建。

所以本质上我有一个名为“CreateHubConnection”的函数,它可以完成您期望的功能,并且我有一个异步方法来启动服务器连接,如下所示:

private async Task ConnectToServer()
{
    // keep trying until we manage to connect
    while (true)
    {
        try
        {
            await CreateHubConnection();
            await this.Connection.StartAsync();
            return; // yay! connected
        }
        catch (Exception e) { /* bugger! */}
    }
}

我的初始连接在新任务中运行它:

this.Cancel = new CancellationTokenSource();
Task.Run(async () => await ConnectToServer(), this.Cancel.Token);

Connection.Closed 处理程序也在新任务中启动它:

this.Connection.Closed += async () => 
{
    try
    {
        await Task.Delay(1000); // don't want to hammer the network
        this.Cancel = new CancellationTokenSource();
        await Task.Run(async () => await ConnectToServer(), this.Cancel.Token);
    }
    catch (Exception _e) { /* give up */ }
}

我不知道为什么这是必要的,但直接从 Closed 处理程序调用 StartAsync 似乎会在 SignalR 库内造成某种死锁。我从来没有追查过这个问题的确切原因......这可能是因为我最初对 StartAsync 的调用是由 GUI 线程调用的。将连接放入自己的线程中,每次创建新的 HubConnections,并处理不再需要的旧 HubConnections 修复它。

如果对此有更多了解的人有更好/更简单的解决方案,我会非常感兴趣。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在正常运行时间较长后,服务器端 SignalR 连接失败 的相关文章

  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 对使用“Identity as UI”的 Web 应用程序验证 .NET Core 2.1 SignalR 控制台客户端

    使用 NET Core 2 1 和 VS2017 预览版 2 我创建了一个简单的 Web 服务器 其中包含 Identity as UI 如下所述here http www talkingdotnet com how to scaffold
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 按字典顺序对整数数组进行排序 C++

    我想按字典顺序对一个大整数数组 例如 100 万个元素 进行排序 Example input 100 21 22 99 1 927 sorted 1 100 21 22 927 99 我用最简单的方法做到了 将所有数字转换为字符串 非常昂贵
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • App Insights 升级到 2.5 后,Azure 应用服务将无法启动

    我有一个存储库 它使用应用程序洞察来记录有关在 ASP NET 中运行的服务的信息 我们有一些 ASP NET Core 2 0 站点以及一些完整框架的 asp net 4 应用程序 随着应用程序洞察 2 5 的发布 我们在核心站点中获得了
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • asp.net cookie、身份验证和会话超时

    我有一个使用表单身份验证的 asp net 网站 我在会话中保留一些信息 例如用户名 用户 ID 电子邮件等 我通过在身份验证 cookie 上设置较长的到期日期来允许用户保持登录网站的状态 因此 当用户仍处于身份验证状态时 会话过期的情况
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 将 viewbag 从操作控制器传递到部分视图

    我有一个带有部分视图的 mvc 视图 控制器中有一个 ActionResult 方法 它将返回 PartialView 因此 我需要将 ViewBag 数据从 ActionResult 方法传递到 Partial View 这是我的控制器

随机推荐

  • 1分30秒倒计时器javascript

    我有代码 但它适用于 2 分钟计时器 我需要将其修改为 1 分 30 秒计时器 我已经尝试过 但未能从 1 30 开始计时器 因为我是这一行的初学者 并且想学习如何做到这一点 这是代码 div div
  • FastAPI - 在 swagger 中添加路径参数的描述

    想象一下有一个这样的应用程序 from fastapi import FastAPI app FastAPI app get items item id async def read item item id int return item
  • ASP.NET Core 授权权限访问文件夹与Identity Server

    在我的 ASP NET Core 项目中 我与 Identity Server 集成 因此 用户必须登录 Identity Server 然后才能访问该应用程序 设计部门给了我一些 HTML5 静态页面来发布 但只有经过身份验证的人或具有特
  • 如何在 VSCode 中创建自定义对话框?

    我正在开发 VSCode 的扩展 我想显示一个自定义对话框来帮助用户配置 ini 文件 是否可以创建带有标签和输入的自定义对话框 您无法创建新的 UI 元素 但如果您想从用户那里获取输入 您可以使用如下代码 let options Inpu
  • Relay/ICommand 与 DelegateCommand——差异

    据我所知 下面的代码可以从 Relay ICommand 命令更改为 Delegate 命令 并且仍然以相同的方式绑定命令 如果我错了 它们的区别和用途是什么 private DelegateCommand something public
  • “功能性”Rust 对性能有哪些影响?

    我正在关注 Rust 轨道运动 io https exercism io 我有相当多的 C C 经验 我喜欢 Rust 的 功能 元素 但我担心相对性能 我解决了 行程编码 问题 https exercism io tracks rust
  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • 在映射器的单个输出上运行多个减速器

    我正在使用地图缩减实现左连接功能 左侧有大约 6 亿条记录 右侧有大约 2300 万条记录 在映射器中 我使用左连接条件中使用的列来创建键 并将键值输出从映射器传递到减速器 我遇到性能问题 因为两个表中的值数量都很高的映射器键很少 例如分别
  • OpenArgs 为空问题

    我正在使用OpenArgs使用时发送值的参数DoCmd OpenForm DoCmd OpenForm frmSetOther acNormal acFormAdd acDialog value 然后我用Me OpenArgs在打开的表格内
  • 从元素中删除 jquery imgareaselect 插件

    所以我使用这个简洁的 jquery 插件http odyniec net projects imgareaselect http odyniec net projects imgareaselect 它工作正常 但我用 jquery ui
  • 如何在 Google App Engine 的 Python 中获取 StringProperty 的值?

    如何获取 nbd Model 的值 我想返回由多个字段组成的描述 但我无法让它工作 这是我的班级代码 class User ndb Model name ndb StringProperty email ndb StringProperty
  • 当 MIDL 无法创建 tlb 时该怎么办?

    我正在尝试创建一个 C inproc 服务器sbtsv idl 它包含在 Windows 8 SDK 中 几乎我的每一个指示 https stackoverflow com questions 1307675 convert interfa
  • 执行页面的 javascript 后保存页面的 html 输出

    我正在尝试抓取一个网站 它首先加载 html js 使用js修改表单输入字段 然后使用POST 如何获得 POSTed 页面的最终 html 输出 我尝试使用 phantomjs 执行此操作 但它似乎只有渲染图像文件的选项 谷歌搜索表明这应
  • 在使用第三方东西时如何保持 Browserify 包大小合理(如果重要的话通过 grunt )

    我正在尝试捆绑我自己的代码 A 该代码又使用 2 个第三方组件 B 和 C 其中 C 也需要 B 据我所知 所有内容都是使用 CommonJS 节点样式模块编写的 捆绑后单独使用的价格为 60K B 是单独包含的 并假定是全局的 我通过在构
  • css 字体 twitter 像关闭按钮一样,我错过了什么?

    twitter 有一个关闭按钮 它是单个字符 x 我需要类似的东西 但是在我检查之后 span x span 我按照 firebug 告诉我的那样创建 css 规则 close button font family Tahoma Arial
  • GLSL NVidia 方形神器

    当 GLSL 着色器在以下 GPU 上生成不正确的图像时 我遇到了问题 GT 430 GT 770 GTX 570显卡760 但在这些上正常工作 英特尔高清显卡 2500英特尔高清4000英特尔4400显卡740MRadeon HD 631
  • htaccess 重写 url 删除子目录

    我正在尝试重写 http www example com directory folder to http www example com directory htaccess 文件位于directory 这是我的 htaccess 文件
  • TextView 宽度匹配drawableTop 宽度

    有什么办法可以使TextView width匹配复合可绘制宽度 XML 例如对于 xml 代码
  • 这个按位运算如何检查 2 的幂?

    我正在看一些应该很简单的代码 但我的数学在这里严重失败 下面是一个使用以下条件检查数字是否为 2 的幂的条件 if num 1 num num 1 make num pow of 2 我的问题是 如何在 num 和 num 1 之间使用按位
  • 在正常运行时间较长后,服务器端 SignalR 连接失败

    我在 StackOverflow 上搜索了许多与 SignalR 连接相关的其他问题 但似乎都不适用于我的具体情况 我有一个使用 SignalR 集线器的应用程序 客户端可以使用两种方法连接到集线器 通过使用底层客户端连接到集线器的 NET