问题描述
用户在浏览器中提交表单后,我需要从服务器向客户端发送即时消息.
I need to send an instant message from the server to the client after the user has submitted a form in a browser.
我按照Microsoft的步骤此处以建立signalR连接,创建Hub类,signalr.js等.
I followed the Microsoft steps here to set up a signalR connection, created a Hub class, signalr.js etc.
问题是我只能向所有客户端调用一条消息,但是我需要向发起请求的特定调用者调用该消息(否则每个人都会收到该消息).
The problem is that I can only invoke a message to all clients, but I need to invoke the message to the specific caller who initiated the request (otherwise everyone will get the message).
这是我在HomeController.cs中的POST操作:
This is my POST Action in the HomeController.cs:
[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文件:
my client javascript file:
//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)
I have tried debugging the action method and I get correctly passed in the connectionId which is "0" (incrementing by 1 per connection)
推荐答案
所以这是我从
我通过从客户端调用Hub类,然后从客户端调用传入connectionId的控制器来获取connectionId.
I got the connectionId by calling the Hub class from client and then from client calling the controller passing in the connectionId.
补习班:
public class SignalHub : Hub
{
public string GetConnectionId()
{
return Context.ConnectionId;
}
}
在启动时执行的客户端javascript代码:
client-side javascript code executed at startup:
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:
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);
}
它可以正常工作,但仍然感觉像是往返,如果我们不必通过集线器类来实现此目的,那会更容易.也许只是从客户端开始具有connectionId,但是也许有充分的理由进行设计:)
It works fine, but still feels a little like a roundtrip, it would have been easier if we didn't have to go through the hub class to make this happen. Maybe just having the connectionId from the client-side to begin with, but maybe there is a good reason for the design :)
这篇关于从控制器ASP.NET Core 2.1到特定客户端的SignalR调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!