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

时间:2013-12-12 14:25:49

标签: c# javascript angularjs signalr

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

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

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

和hub2:

[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控制器:

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.
    };
}]);

在该示例中,对于客户端方法的绑定在signalR启动之后发生很久(在这种情况下,通过按下按钮作为示例,但在实例中,可能是当用户导航到不同的ng-时查看模板,用它启动一个不同的角度控制器,这也取决于客户端方法)。在测试中我看到我必须向每个集线器添加一个客户端方法(虚拟或非虚拟),以便稍后在另一个角度控制器的启动时添加额外的客户端方法。我想知道是否可以这样做,所以你没有为客户端方法获得一长串绑定虚函数?

此外,使用on函数似乎并不合适,在连接启动后,直接绑定似乎也能正常工作。也许这在SignalR版本2.0.0中已经改变

1 个答案:

答案 0 :(得分:0)

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

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