【问题标题】:In SignalR, is it possible to simulate a reconnect for testing?在 SignalR 中,是否可以模拟重新连接以进行测试?
【发布时间】:2022-04-11 18:32:26
【问题描述】:

我了解,如果连接因任何原因失败,SignalR 会不断尝试重新连接。测试我的服务器和客户端对此的响应的最佳方法是什么?

【问题讨论】:

    标签: c# asp.net signalr


    【解决方案1】:

    为了让客户端尝试重新连接,您需要使用withAutomaticReconnect 方法配置HubConnectionBuilder。 JavaScript 代码如下所示:

    const connection = new signalR.HubConnectionBuilder()
      .withUrl(`${apiUrl}/subscribe/change`)
      .withAutomaticReconnect()
      .build();
    

    一旦设置好,客户端将在连接丢失时尝试重新连接。

    在内部,当 SignalR 断开连接时,它会调用 stopInternal 函数。

    如果您想进行一些手动测试以确保您的处理程序被解雇并且他们会按照您的期望进行操作。您可以将连接保存在 const 中并自己触发事件。

    我做了什么:

    1. 像上面的代码一样创建了连接,
    2. 将连接缓存在window 对象中。
        window.signalR = connection;
    
    1. 打开浏览器控制台,点击左边的三个点,导航到Network conditions

    1. 已将Network throttling 更新为离线。

    1. 最后跑了:
    signalR.connection.stopInternal();
    

    我的onreconnecting 处理程序开始触发。它默认运行 4 次。它看起来像这样:

    connection.onreconnecting(error => {
      console.log('Reconnecting interval', error);
    });
    

    注意:此策略仅用于开发和一些手动测试。我不建议将window 对象用于单元测试或集成测试。

    类似的策略可以通过在单元测试使用的一些内部变量上缓存连接来实现。

    【讨论】:

    • 这是一个很好的解决方案,但我的客户端是一个 UWP 应用程序。我想知道我是否可以对防火墙做同样的事情?
    【解决方案2】:

    我在这里找到了解决方案:https://stackoverflow.com/a/59916046/2929675

    在打开 WebSocket 连接之前,您必须执行此脚本来猴子修补浏览器的 WebSocket 功能:

    const sockets = [];
    const nativeWebSocket = window.WebSocket;
    window.WebSocket = function(...args){
      const socket = new nativeWebSocket(...args);
      sockets.push(socket);
      return socket;
    };
    

    现在您可以通过 sockets 数组访问所有 WebSocket 连接。 而当你想触发重连时,你可以调用

    sockets[0].close();
    

    使用要关闭的连接的索引。

    启用 SignalR 自动重新连接后,它将自动尝试打开新连接,并触发 ReconnectingReconnected 事件。

    这有点hacky,但这是我迄今为止找到的最佳解决方案。

    看起来铬问题也有一些进展,以在开发工具中支持这一点:https://bugs.chromium.org/p/chromium/issues/detail?id=423246

    【讨论】:

      【解决方案3】:

      在服务器上测试断开连接:浏览到另一个页面。

      在客户端测试断开连接:重置服务器(IISreset?)。

      【讨论】:

      • 你错了。要在服务器关闭后测试重新连接,请使用 iisreset。模拟客户端连接断开(祝你好运)拉网线:)
      • 所以,你的意思是......你真的需要两端来创建连接吗?您是否创建了 SignalR 之类的?!?啊,我明白了……你做到了! - 低头慢慢向后走 -
      • 在使用 Azure SignalR 服务时,拉网线无法准确模拟客户端连接断开。由于您的开发机器通过 Internet 连接到 ASRS,因此它的行为类似于您运行 iisreset 时发生的情况;所有客户端被强制断开等
      【解决方案4】:

      为 TypeScript 更新了 berhir 的 sn-p

      class MockWebSocket extends WebSocket {
          static sockets: WebSocket[] = [];
      
          constructor(url: string | URL, protocols?: string | string[]) {
              super(url, protocols);
      
              MockWebSocket.sockets.push(this);
          }
      }
      window.WebSocket = MockWebSocket;
      

      关闭一个套接字:

      MockWebSocket.sockets[index].close();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-14
        • 1970-01-01
        • 1970-01-01
        • 2021-06-29
        • 1970-01-01
        • 2011-11-22
        • 2012-02-22
        • 1970-01-01
        相关资源
        最近更新 更多