SignalR 从控制器 ASP.NET Core 2.1 调用特定客户端
SignalR call to specific client from controller ASP.NET Core 2.1
用户在浏览器中提交表单后,我需要从服务器向客户端发送即时消息。
我按照 Microsoft 的步骤 here 设置了 signalR 连接,创建了集线器 class、signalr.js 等
问题是我只能向所有客户端调用消息,但我需要向发起请求的特定调用者调用消息(否则每个人都会收到消息)。
这是我在 HomeController.cs 中的 POST 操作:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Submit(string signalRconnectionId, Dictionary<string, string> inputs)
{
//Invoke signal to all clients sending a message to initSignal WORKS FINE
await _signalHubContext.Clients.All.SendAsync("initSignal", "This is a message from the server!");
//Invoke signal to specified client where signalRConnectionId = connection.id DOES NOT WORK
await _signalHubContext.Clients.Client(signalRconnectionId).SendAsync("initSignal", "This is a message from server to this client: " + signalRconnectionId);
return RedirectToAction("Success", inputs);
}
我的客户javascript 文件:
//Create connection and start it
const connection = new signalR.HubConnectionBuilder()
.withUrl("/signalHub")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start().catch(err => console.error(err.toString()));
console.log("connectionID: " + connection.id);
$("#signalRconnectionId").attr("value", connection.id);
//Signal method invoked from server
connection.on("initSignal", (message) => {
console.log("We got signal! and the message is: " + message);
});
我已经尝试调试操作方法,我正确地传入了“0”的 connectionId(每个连接递增 1)
根据 Microsoft 的说法,您无法从集线器外部访问 ConnectionId 和 Caller
https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-2.1
When hub methods are called from outside of the Hub
class, there's no
caller associated with the invocation. Therefore, there's no access to
the ConnectionId
, Caller
, and Others
properties.
这是我根据
的答案得出的最终解决方案
我通过从客户端调用 Hub class 获得了 connectionId,然后从客户端调用传入 connectionId 的控制器。
中心 class:
public class SignalHub : Hub
{
public string GetConnectionId()
{
return Context.ConnectionId;
}
}
客户端javascript启动时执行的代码:
connection.start().catch(err => console.error(err.toString())).then(function(){
connection.invoke('getConnectionId')
.then(function (connectionId) {
// Send the connectionId to controller
console.log("connectionID: " + connectionId);
$("#signalRconnectionId").attr("value", connectionId);
});
});
HomeController.cs:
public async Task<IActionResult> Submit(string signalRconnectionId, Dictionary<string, string> inputs)
{
//Invoke signal to specified client WORKS NOW
await _signalHubContext.Clients.Client(signalRconnectionId).SendAsync("initSignal", "This is a message from server to this client: " + signalRconnectionId);
return RedirectToAction("Success", inputs);
}
它工作正常,但仍然感觉有点像往返,如果我们不必通过枢纽 class 来实现它会更容易。也许只是从客户端开始使用 connectionId,但也许有一个很好的设计理由:)
用户在浏览器中提交表单后,我需要从服务器向客户端发送即时消息。
我按照 Microsoft 的步骤 here 设置了 signalR 连接,创建了集线器 class、signalr.js 等
问题是我只能向所有客户端调用消息,但我需要向发起请求的特定调用者调用消息(否则每个人都会收到消息)。
这是我在 HomeController.cs 中的 POST 操作:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Submit(string signalRconnectionId, Dictionary<string, string> inputs)
{
//Invoke signal to all clients sending a message to initSignal WORKS FINE
await _signalHubContext.Clients.All.SendAsync("initSignal", "This is a message from the server!");
//Invoke signal to specified client where signalRConnectionId = connection.id DOES NOT WORK
await _signalHubContext.Clients.Client(signalRconnectionId).SendAsync("initSignal", "This is a message from server to this client: " + signalRconnectionId);
return RedirectToAction("Success", inputs);
}
我的客户javascript 文件:
//Create connection and start it
const connection = new signalR.HubConnectionBuilder()
.withUrl("/signalHub")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start().catch(err => console.error(err.toString()));
console.log("connectionID: " + connection.id);
$("#signalRconnectionId").attr("value", connection.id);
//Signal method invoked from server
connection.on("initSignal", (message) => {
console.log("We got signal! and the message is: " + message);
});
我已经尝试调试操作方法,我正确地传入了“0”的 connectionId(每个连接递增 1)
根据 Microsoft 的说法,您无法从集线器外部访问 ConnectionId 和 Caller https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-2.1
When hub methods are called from outside of the
Hub
class, there's no caller associated with the invocation. Therefore, there's no access to theConnectionId
,Caller
, andOthers
properties.
这是我根据
我通过从客户端调用 Hub class 获得了 connectionId,然后从客户端调用传入 connectionId 的控制器。
中心 class:
public class SignalHub : Hub
{
public string GetConnectionId()
{
return Context.ConnectionId;
}
}
客户端javascript启动时执行的代码:
connection.start().catch(err => console.error(err.toString())).then(function(){
connection.invoke('getConnectionId')
.then(function (connectionId) {
// Send the connectionId to controller
console.log("connectionID: " + connectionId);
$("#signalRconnectionId").attr("value", connectionId);
});
});
HomeController.cs:
public async Task<IActionResult> Submit(string signalRconnectionId, Dictionary<string, string> inputs)
{
//Invoke signal to specified client WORKS NOW
await _signalHubContext.Clients.Client(signalRconnectionId).SendAsync("initSignal", "This is a message from server to this client: " + signalRconnectionId);
return RedirectToAction("Success", inputs);
}
它工作正常,但仍然感觉有点像往返,如果我们不必通过枢纽 class 来实现它会更容易。也许只是从客户端开始使用 connectionId,但也许有一个很好的设计理由:)