我正在学习如何一起使用 AngularJS 和 SignalR,我想知道是否可以重新启动 SignalR 连接而不丢失服务器端的 connectionId。我问这个问题的原因与需要在服务器端调用的客户端方法有关。我还没有尝试过任何东西,我只是在考虑这种情况以及最佳实践解决方案是什么,我希望有人能够思考或者可能有解决方案并愿意解释一下。
例如:我有两个 angularJS Controller ,controller1
和 controller2
以及两个 signalR 集线器,hub1
和 hub2
>。 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 中发生了变化
最佳答案
要尝试一下,我想我明白你在问什么,所以我会提供一些指导:
- 为了维护连接 ID 而重新启动 SignalR 连接并不是一个好主意。相反,通过某种静态并发字典来跟踪中心中的用户。这样,当从特定用户建立连接时,您可以将它们与该用户的字典版本相关联。
- 在启动 SignalR 连接 (JavaScript) 之前,您必须至少绑定(bind) 1 个客户端函数;此过程允许 SignalR 订阅您想要订阅的集线器。
希望这有帮助!
关于c# - 是否可以重新启动/重新连接 SignalR 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20546119/