c# - SignalR 从 Controller ASP.NET Core 2.1 调用特定客户端

标签 c# asp.net-mvc asp.net-core asp.net-core-signalr

用户在浏览器中提交表单后,我需要从服务器向客户端发送即时消息。

我遵循了 Microsoft 的步骤 here设置一个 signalR 连接,创建一个 Hub 类,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);


});

我已经尝试调试 action 方法,我得到了正确传递的 connectionId,它是“0”(每个连接递增 1)

最佳答案

因此,这是我根据 this thread 的答案得出的最终解决方案。

我通过从客户端调用 Hub 类获得 connectionId,然后从客户端调用传入 connectionId 的 Controller 。

中心类:

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);
    }

它工作正常,但仍然感觉有点像往返,如果我们不必通过 hub 类来实现它会更容易。也许只是从客户端开始使用 connectionId,但也许设计有充分的理由 :)

关于c# - SignalR 从 Controller ASP.NET Core 2.1 调用特定客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51821081/

相关文章:

c# - 是否可以在没有 SQL Server 的情况下访问 .mdf 数据库?

c# - C#-随机数生成器错误

C#驱动开发?

asp.net-mvc - 如何使用 jqgrid 和 http 方法 POST 将额外的参数传递给服务器?

azure - 在 ASP.NET Core 应用程序之间共享静态 Assets (或通过 Azure CDN?)

asp.net-core - 如何覆盖默认的 Windows Authentiation ClaimsPrincipal User 和 Authorize Controller 方法属性

c# - WPF - 将参数从对话框窗口传递给用户控件

asp.net - web.config 中 ApiURIs-ISAPI-Integrated-4.0 的多个路径

asp.net-mvc - Nhibernate CreateSQLQuery 存储过程结果到非映射类

c# - 将嵌套对象发送到asp.net core Get方法