簡體   English   中英

無法使用 SignalR 向特定用戶發送消息

[英]Can't send message to specific user with SignalR

我無法使從背后的代碼發送給特定用戶的消息起作用。 Clients.All有效, Clients.AllExcept(userId)有效,但Client.User(userId)

我的樞紐:

public class MessagingHub : Hub
{
    public override Task OnConnected()
    {
        var signalRConnectionId = Context.ConnectionId;
        // for testing purpose, I collect the userId from the VS Debug window
        System.Diagnostics.Debug.WriteLine("OnConnected --> " + signalRConnectionId);
        return base.OnConnected();
    }
}

我的控制器從后面的代碼發送消息:

public void PostMessageToUser(string ConnectionId)
{
    var mappingHub = GlobalHost.ConnectionManager.GetHubContext<MessagingHub>();

    // doesn't works
    mappingHub.Clients.User(ConnectionId).onMessageRecorded();

    // doesn't works
    mappingHub.Clients.Users(new List<string>() { ConnectionId }).onMessageRecorded();

    // works
    mappingHub.Clients.All.onMessageRecorded();

    // works (?!)
    mappingHub.Clients.AllExcept(ConnectionId).onMessageRecorded();

}

我的集線器如何在 JS 上初始化:

var con, hub;
function StartRealtimeMessaging()
{
    con = $.hubConnection();
    hub = con.createHubProxy('MessagingHub');

    hub.on('onMessageRecorded', function () {
        $(".MessageContainer").append("<div>I've received a message!!</div>");
    });
    con.start();
}

最后我如何向集線器發送(n 空)消息:

function TestSendToUser(connectionId)
{
    $.ajax({
        url: '/Default/PostMessageToUser',
        type: "POST",
        data: { ConnectionId: connectionId},// contains the user I want to send the message to
    });
}

因此,它與mappingHub.Clients.All.onMessageRecorded();完美配合mappingHub.Clients.All.onMessageRecorded(); 但不是mappingHub.Clients.User(ConnectionId).onMessageRecorded(); mappingHub.Clients.Users(new List<string>() { ConnectionId}).onMessageRecorded(); .

有趣的是,它適用於mappingHub.Clients.AllExcept(ConnectionId).onMessageRecorded(); : 除給定的userid 外,所有連接的用戶都收到消息,說明userid 是好的,並且用戶被很好地識別。 那么,為什么Clients.User(ConnectionId)不起作用?

我有同樣的問題。 我無法讓 .User(ConnectionId) 工作。

我剛剛花了幾天時間試圖讓 SignalR 僅向請求該工作的客戶報告一個長時間處理工作的進度。 也就是說,它不是大多數示例所描述的聊天應用程序。

我發現的任何“長處理進度報告”示例都只有集線器中的工作模擬。 我有一個控制器在做實際工作,需要從控制器而不是集線器發送消息。

我使用了這個答案https://stackoverflow.com/a/21222303/3251300 作為您所述問題的解決方法,但已包含我用於長時間處理工作的所有代碼片段,以防它們對任何偶然發現此答案的人有用。

該解決方法的優雅之處在於它使用了 .Group() 功能。 通過將每個 groupID 設置為等於內部 userID,可以使用 .Group(userID) 發送消息,而無需在 SignalR 之外單獨維護 userID/connectionID 關系列表。

可能有一種方法可以在不使用 .Group() 功能的情況下維護 SignalR 中的關系,但我還沒有找到。

使用隱藏類型將用戶 ID 傳遞給視圖,然后使其可用於 js。

 <input type="hidden" value="@ViewBag.UserID" id="userID" />

然后在 js 集線器腳本中使用以下內容在集線器連接啟動時將用戶 ID 發送到集線器。

$.connection.hub.start()
  .done(function () {
    var userID = document.getElementById('userID').value;
    $.connection.myHub.server.announce(userID);
   })
  .fail(function () { alert("Hub failed to start.") });

然后,集線器有一個語句將 userID 和 connectionID 與 groupID 相關聯,然后 groupID 與 userID 是相同的字符串。

 public class MyHub : Hub
   {
       public void Announce(string userID)
       {
           Groups.Add(Context.ConnectionId, userID);
       }
   }

要在設置集線器上下文后從控制器發送消息(同樣,在這種情況下不是集線器,消息是在控制器中運行的長處理請求上向客戶端報告進度),請使用 .Group() 和內部用戶 ID。

var hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
string fileMessage = "Some message";
hubContext.Clients.Group(userID).hubMessage(fileMessage);

然后在視圖中顯示使用 js 將消息放置在 div 中

$.connection.myHub.client.hubMessage = function (message) {
   $("#hubMessages").html(message);
}

'#hubMessages' 指的是視圖中的這個 div。 示例使用 .append 使每次發送消息時 div 增長,.HTML 用新消息替換 div 中的任何內容。

 <div id="hubMessages"></div>

任何得到這個答案並試圖繼續使用 MVC 和 SignalR 的人,都要向 Caleb 大喊大叫,他為 SignalR 提供了一系列精彩的介紹視頻https://youtu.be/kr8uHeNjOKw任何找到這個答案的新人到 SignalR 我建議你花一個小時看這些。

如果您想向一個特定的連接發送消息並且當您想使用ConnectionId ,請確保您使用Clients.Client而不是Clients.User

像這樣:

public void PostMessageToUser(string connectionId)
{
    var mappingHub = GlobalHost.ConnectionManager.GetHubContext<MessagingHub>();

    // Like this
    mappingHub.Clients.Client(connectionId).onMessageRecorded();

    // or this
    mappingHub.Clients.Clients(new List<string>() { connectionId }).onMessageRecorded();
}

我面臨同樣的問題。

我從:

Clients.User(connectionId).SendAsync(CallbackDefinition.DirectMessage, directMessageResult);

到:

Clients.Client(connectionId).SendAsync(CallbackDefinition.DirectMessage, directMessageResult);

它工作:D

感謝:Matthieu Charbonnier

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM