首页 文章

SignalR从控制器ASP.NET Core 2.1调用特定客户端

提问于
浏览
1

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

我按照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)

2 回答

  • 2

    所以这是我想出的最终解决方案的灵感来自this thread

    我通过从客户端调用Hub类,然后从客户端调用传递connectionId的控制器来获取connectionId .

    枢纽类:

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

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

  • 0

    根据Microsoft的说法,您无法从集线器外部访问ConnectionId和Caller https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext?view=aspnetcore-2.1

    当从Hub类外部调用hub方法时,没有与调用关联的调用方 . 因此,无法访问ConnectionId,Caller和Others属性 .

相关问题