将 signalr 与 web api 集成以向客户端推送通知
Integrate signalr with web api to push notifications to clients
我开发一个应用程序,服务器端技术是asp.net web api,客户端是javascript。在我的应用程序中,我使用 Signalr 通知客户端更新 - 从服务器向客户端推送通知。
由于来自 HTTP 请求的推送而不是客户端通过 signalr 推送到服务器,因此所有信号器交互都发生在集线器之外 class。
在处理成功的 HTTP 请求后,我想让除了提交请求的客户端之外的所有客户端都得到通知。
谁应该对这些通知负责?处理合法请求后,我的服务器是否应该只向客户端推送通知? (这就是我目前所做的)如果这是要走的路,除了提出请求的客户之外,我该如何通知所有客户?提醒 - 因为请求是 Http 而不是 signalr 推送,所以对客户端的推送发生在集线器之外的 class 中。因此,我不能像您可能建议的那样使用 Context 或 Client.Others 属性。我怎么知道应该通知哪些客户?目前我只使用 Clients.All 并且发出请求的人也会收到我不喜欢的通知。
选项 2 是在我的服务器响应成功状态代码之后。发出请求的客户端将负责通知其他客户端 - 这意味着他会将消息推送到服务器,然后服务器会将通知推送到所有其他客户端(这次它将在 signalr Hub 内,所以我可以使用Clients.Others).
我应该采用哪种方法?
我认为您的第一种方法是无缝的,并且很容易实施。另外,您不希望用户负责通知。用户是懒惰的。
所以基本上在你 'processed' 你的请求并且你没有捕获到任何异常之后,你将获得你的 SignalR Hub 上下文并使用内置的 SignalR C# API 来广播发给每个客户的消息 除了 发件人。
这里有一些代码可以进入您的 Controller
:
[Route("ProcessMessage")]
public async void ProcessMessage(string[] clientConnectionStrings)
{
// do some processing
var hub = GlobalHost.ConnectionManager.GetHubContext<MessagingHub>();
hub.Clients.AllExcept(clientConnectionStrings);
}
您必须传入客户端的连接 ID 才能使用 AllExcept
,但这应该是一个相当容易的集成。 (注意:如果您直接与 SignalR Hub 交互,则不必执行此操作)
注意:要让客户端的连接从您的广播中排除,您可以像这样访问它:
$.connection.hub.id
另一种方法是直接使用 SignalR Hub,但需要额外的 JavaScript 代码来触发 Hub 服务器上的事件。例如:
$.ajax({
url: 'Some/Url/',
type: 'POST',
success: function (data) {
connection.server.someDataChangeEvent();
},
error: function (ex) { return; }
});
SignalR 中心代码:
public void SomeDataChangeEvent(string connId)
{
Clients.Others.updateData(_someDataStore.getUpdates().ToList());
}
客户代码:
connection.client.updateData = function() {
//do stuff
}
我开发一个应用程序,服务器端技术是asp.net web api,客户端是javascript。在我的应用程序中,我使用 Signalr 通知客户端更新 - 从服务器向客户端推送通知。
由于来自 HTTP 请求的推送而不是客户端通过 signalr 推送到服务器,因此所有信号器交互都发生在集线器之外 class。
在处理成功的 HTTP 请求后,我想让除了提交请求的客户端之外的所有客户端都得到通知。
谁应该对这些通知负责?处理合法请求后,我的服务器是否应该只向客户端推送通知? (这就是我目前所做的)如果这是要走的路,除了提出请求的客户之外,我该如何通知所有客户?提醒 - 因为请求是 Http 而不是 signalr 推送,所以对客户端的推送发生在集线器之外的 class 中。因此,我不能像您可能建议的那样使用 Context 或 Client.Others 属性。我怎么知道应该通知哪些客户?目前我只使用 Clients.All 并且发出请求的人也会收到我不喜欢的通知。
选项 2 是在我的服务器响应成功状态代码之后。发出请求的客户端将负责通知其他客户端 - 这意味着他会将消息推送到服务器,然后服务器会将通知推送到所有其他客户端(这次它将在 signalr Hub 内,所以我可以使用Clients.Others).
我应该采用哪种方法?
我认为您的第一种方法是无缝的,并且很容易实施。另外,您不希望用户负责通知。用户是懒惰的。
所以基本上在你 'processed' 你的请求并且你没有捕获到任何异常之后,你将获得你的 SignalR Hub 上下文并使用内置的 SignalR C# API 来广播发给每个客户的消息 除了 发件人。
这里有一些代码可以进入您的 Controller
:
[Route("ProcessMessage")]
public async void ProcessMessage(string[] clientConnectionStrings)
{
// do some processing
var hub = GlobalHost.ConnectionManager.GetHubContext<MessagingHub>();
hub.Clients.AllExcept(clientConnectionStrings);
}
您必须传入客户端的连接 ID 才能使用 AllExcept
,但这应该是一个相当容易的集成。 (注意:如果您直接与 SignalR Hub 交互,则不必执行此操作)
注意:要让客户端的连接从您的广播中排除,您可以像这样访问它:
$.connection.hub.id
另一种方法是直接使用 SignalR Hub,但需要额外的 JavaScript 代码来触发 Hub 服务器上的事件。例如:
$.ajax({
url: 'Some/Url/',
type: 'POST',
success: function (data) {
connection.server.someDataChangeEvent();
},
error: function (ex) { return; }
});
SignalR 中心代码:
public void SomeDataChangeEvent(string connId)
{
Clients.Others.updateData(_someDataStore.getUpdates().ToList());
}
客户代码:
connection.client.updateData = function() {
//do stuff
}