我正在尝试将SignalR添加到我的Angular MVC应用程序中。 我使用本文作为起点,它有一个集线器代理工厂,它用于...井。。。代理中心调用。我已经设置好了所有内容,但是服务器上的集线器无法与我的 Angular 代码通信。 这是我的代码:
集线器代理工厂:
app.factory('hubProxy', ['$rootScope', 'signalRUrl', function ($rootScope, signalRUrl) {
function hubFactory(hubName) {
var connection = $.hubConnection(signalRUrl);
var proxy = connection.createHubProxy(hubName);
connection.start().done(function () { });
return {
on: function (eventName, callback) {
proxy.on(eventName, function (result) {
$rootScope.$apply(function () {
if (callback) {
callback(result);
}
});
});
},
invoke: function (methodName, callback) {
proxy.invoke(methodName)
.done(function (result) {
$rootScope.$apply(function () {
if (callback) {
callback(result);
}
});
});
},
connection: connection
};
};
return hubFactory;
}]);
角度控制器:
angular.module('testApp').controller('testController', ['$scope', 'hubProxy', function ($scope, hubProxy) {
var pendingPaymentsHub = hubProxy('pendingPaymentsHub');
pendingPaymentsHub.on('onUpdatePendingPayment', function (data) {
console.log('hub callback!');
});
}]);
枢纽:
[HubName("pendingPaymentsHub")]
public class PendingPaymentsHub : Hub
{
private static IHubContext hub = GlobalHost.ConnectionManager.GetHubContext<PendingPaymentsHub>();
public static void UpdatePendingPayment(PendingPaymentViewModel pendingPayment)
{
hub.Clients.All.onUpdatePendingPayment(pendingPayment);
}
}
在本例中,更新完成后,从 API 控制器调用我的中心。 它被称为:
PendingPaymentsHub.UpdatePendingPayment(pendingPayment);
当页面加载时,/signalr/negotiate
和/signalr/start
调用都成功运行(在浏览器开发工具中确认 200 秒)。 我还可以确认我的中心中的UpdatePendingPayment
方法是否通过调试命中。 我在前端什么也没得到。 为什么?
提前谢谢。
更新:需要明确的是,问题出在集线器代理工厂上。 当我在控制器中将工厂实现替换为以下内容时,一切都按预期工作:
function initializeHub() {
connection = $.hubConnection(signalRUrl);
hub = connection.createHubProxy('pendingPaymentsHub');
hub.on('onUpdatePendingPayment', function (data) {
console.log('success');
});
connection.start();
};
客户端的服务器端方法调用大写,即使它在客户端以小写开头:
hub.Clients.All.OnUpdatePendingPayment(pendingPayment);
检查生成的代理以查看完成了什么方法映射,这是我发现大写问题的地方。
方法拼写错误、方法签名不正确或中心名称不正确的要点涵盖了这一点,代理使用 camelCase:
[...]此外,SignalR 使用驼峰大小写方法创建中心代理,如 在 JavaScript 中是合适的,因此一个名为 SendMessage 的方法在 服务器将在客户端代理中称为 sendMessage。
在从完全相同的教程中工作,我相信问题是您必须在为 hubProxy 对象定义 .on() 方法之后调用 connection.start() -。我不知道在这种情况下教程示例应该如何工作。
这是我重做的服务:
app.factory('hubProxy', ['$rootScope', 'serverUrl', function ($rootScope, serverUrl) {
function backendFactory(hubName) {
$.support.cors = true;
var connection = $.hubConnection(serverUrl);
var proxy = connection.createHubProxy(hubName);
return {
on: function (eventName, callback) {
proxy.on(eventName, function (result) {
$rootScope.$apply(function () {
if (callback) {
callback(result);
}
});
});
},
invoke: function (methodName, callback) {
proxy.invoke(methodName)
.done(function (result) {
$rootScope.$apply(function () {
if (callback) {
callback(result);
}
});
});
},
start: function(){
connection.start().done(function () { });
}
};
};
return backendFactory;
}]);
那么你只需要在调用 on() 方法后调用 start():
app.controller('hubDataController', ['$scope', 'hubProxy',
function ($scope, hubProxy) {
var proxy = hubProxy('remoteHub');
proxy.on('broadcast', function (data) {
console.log(data);
});
proxy.start();
}
]);