c# - 是否可以重新启动/重新连接 SignalR 连接?

标签 c# javascript angularjs signalr

我正在学习如何一起使用 AngularJS 和 SignalR,我想知道是否可以重新启动 SignalR 连接而不丢失服务器端的 connectionId。我问这个问题的原因与需要在服务器端调用的客户端方法有关。我还没有尝试过任何东西,我只是在考虑这种情况以及最佳实践解决方案是什么,我希望有人能够思考或者可能有解决方案并愿意解释一下。

例如:我有两个 angularJS Controller ,controller1controller2 以及两个 signalR 集线器,hub1hub2 >。 controller1 在打开网站时启动,并在 controller1 的初始化中启动,我可以将函数绑定(bind)到需要在 hub1 中调用的客户端方法在 SignalR 启动之前。这工作正常,即使在 signalR 启动后,即使 signalR 启动,我仍然可以使用 on 函数将函数绑定(bind)到客户端方法,尽管这可能不是必需的,因为我可以将函数绑定(bind)到启动 signalR 连接之前的客户端方法。

接下来,在表单上我有一个按钮,该按钮正在启动另一个 div,其中 controller2 作为 ng-controller。在 controller2 的初始化中,我想将函数绑定(bind)到需要在 hub2 中调用的客户端方法。但由于 signalR 连接已由 controller1 启动,因此我无法执行 hub2.client.AMethod = function () { }。我在想,如果我可以重新启动 signalR 连接而不丢失服务器端的 connectionId,并且通过重新启动,还刷新所有客户端方法绑定(bind),这可能吗?如果没有,即使之前 hub2 上没有绑定(bind)到客户端方法的函数,我也可以使用 on 函数吗?或者,在启动 signalR 连接之前,我是否还必须将一个空函数绑定(bind)到 hub2 上的客户端方法?

编辑:我花时间设置了一个代码示例。

我有 2 个集线器:Hub1

[HubName("Hub1")]
public class Hub1 : Hub
{
    public void TestMethod1(string test)
    {
        Clients.All.TestMethod1Hub1("Testing Hub1 method1; " + test);
    }

    public void TestMethod2(string test)
    {
        Clients.All.TestMethod2Hub1("Testing Hub1 method2; " + test);
    }
}

和集线器2:

[HubName("Hub2")]
public class Hub2 : Hub
{
    public void TestMethod1(string test)
    {
        Clients.All.TestMethod1Hub2("Testing Hub2 method1; " + test);
    }

    public void TestMethod2(string test)
    {
        Clients.All.TestMethod2Hub2("Testing Hub2 method2; " + test);
    }
}

我得到了我的 angularJS Controller :

testApp.controller('controller1', ['$scope', 'signalRService', function ($scope, signalRService) {
    var self = this;

    $scope.logs = [];

    self.TestMethod = function(testString) {
        $scope.logs.push({ text: testString });
        $scope.$apply();
    };

    $scope.initialize = function() {
        signalRService.connection.Hub1.client.TestMethod1Hub1 = self.TestMethod;
        //signalRService.connection.Hub2.client.TestMethod1Hub2 = self.TestMethod;
        signalRService.initialize();
    };

    $scope.addHandlers = function () {
        //this will call the client method cause it is set before the connection start.
        signalRService.connection.Hub1.server.testMethod1("Test 1");

        //This is working, so on function isn't required?
        signalRService.connection.Hub1.client.TestMethod2Hub1 = self.TestMethod;
        signalRService.connection.Hub1.server.testMethod2("Test 2");

        //So you don't need the on method (anymore?). (By the way, this is working as well ofcourse)
        signalRService.connection.Hub1.on("TestMethod2Hub1", self.TestMethod);
        signalRService.connection.Hub1.server.testMethod2("Test 3");

        //this doesn't work (obviously?) unless the line in the initalize method is uncommented
        signalRService.connection.Hub2.client.TestMethod1Hub2 = self.TestMethod;
        signalRService.connection.Hub2.server.testMethod1("Test 4");

        //but this doesn't work either. Same: works if line in the initialize method is uncommented
        signalRService.connection.Hub2.on("TestMethod1Hub2", self.TestMethod);
        signalRService.connection.Hub2.server.testMethod1("Test 5");

        //Also, I get the test 4 and test 5 twice, so the event handlers are added, not replaced.
    };
}]);

在示例中,与客户端方法的绑定(bind)发生在 signalR 启动之后很久(在本例中,通过按下按钮作为示例,但在实际示例中,可能是当用户导航到不同的 ng-查看模板并启动一个不同的 Angular Controller ,该 Controller 也取决于客户端方法)。在测试中,我发现我必须向每个集线器添加一个客户端方法(虚拟或非虚拟),以便我可以稍后在另一个 Angular Controller 启动时添加额外的客户端方法。我想知道是否可以通过其他方式完成此操作,这样您就不会得到将虚拟函数绑定(bind)到客户端方法的长列表?

此外,似乎没有必要使用 on 函数,连接启动后立即绑定(bind)似乎也可以工作。也许这在 SignalR 版本 2.0.0 中发生了变化

最佳答案

要尝试一下,我想我明白你在问什么,所以我会提供一些指导:

  1. 为了维护连接 ID 而重新启动 SignalR 连接并不是一个好主意。相反,通过某种静态并发字典来跟踪中心中的用户。这样,当从特定用户建立连接时,您可以将它们与该用户的字典版本相关联。
  2. 在启动 SignalR 连接 (JavaScript) 之前,您必须至少绑定(bind) 1 个客户端函数;此过程允许 SignalR 订阅您想要订阅的集线器。

希望这有帮助!

关于c# - 是否可以重新启动/重新连接 SignalR 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20546119/

相关文章:

AngularJS Firefox HTML 缓存

c# - 如何将选定的按钮显示为标签

c# - 为什么我的兔子队列不会死?

javascript - 将二维数组与键值数组相结合

angularjs - AngularJS 中如何进行分页?

javascript - 查看多个 $scope 属性

c# - 事件是 C# 结构中的吗?

c# - Serilog 是否支持 .NET Framework 4.8

javascript - 当包含 margin-left 和 margin-right 时,图像不会显示在给定位置

javascript - 在 for 循环中访问动态变量名称