首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何获取服务器端signalR客户端的连接ID?

如何获取服务器端signalR客户端的连接ID?
EN

Stack Overflow用户
提问于 2014-01-04 00:47:21
回答 3查看 88.6K关注 0票数 51

我需要获取客户端的连接ID。我知道您可以使用$.connection.hub.id从客户端获得它。我需要的是在web服务中使用它来更新数据库中的记录,然后在网页上显示更新。我是signalR和stackoverflow的新手,因此任何建议都将不胜感激。在我的客户端网页上,我有以下内容:

代码语言:javascript
运行
复制
<script type="text/javascript">
    $(function () {
        // Declare a proxy to reference the hub. 
        var notify = $.connection.notificationHub;

        // Create a function that the hub can call to broadcast messages.
        notify.client.broadcastMessage = function (message) {
            var encodedMsg = $('<div />').text(message).html();// Html encode display message.
            $('#notificationMessageDisplay').append(encodedMsg);// Add the message to the page.
        };//end broadcastMessage

        // Start the connection.
        $.connection.hub.start().done(function () {
            $('#btnUpdate').click(function () {
                //call showNotification method on hub
                notify.server.showNotification($.connection.hub.id, "TEST status");
            });
        });


    });//End Main function


</script>

一切正常,直到我想使用signalR更新页面。在我的集线器中显示通知函数如下:

代码语言:javascript
运行
复制
//hub function
public void showNotification(string connectionId, string newStatus){               
    IHubContext context = GlobalHost.ConnectionManager.GetHubContext<notificationHub>();
    string connection = "Your connection ID is : " + connectionId;//display for testing
    string statusUpdate = "The current status of your request is: " + newStatus;//to be displayed
    //for testing, you can display the connectionId in the broadcast message
    context.Clients.Client(connectionId).broadcastMessage(connection + " " + statusUpdate);
}//end show notification

如何将connectionid发送到我的web服务?

希望我不是在尝试做一些不可能的事情。提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-08-08 17:23:03

泰勒的答案是有效的,然而,它没有考虑到这样一种情况,即用户打开了多个web浏览器标签,因此具有多个不同的连接ID。

为了解决这个问题,我创建了一个并发字典,其中字典键是用户名,每个键的值是该给定用户的当前连接列表。

代码语言:javascript
运行
复制
public static ConcurrentDictionary<string, List<string>> ConnectedUsers = new ConcurrentDictionary<string, List<string>>();

在已连接时-将连接添加到全局缓存字典:

代码语言:javascript
运行
复制
public override Task OnConnected()
{
    Trace.TraceInformation("MapHub started. ID: {0}", Context.ConnectionId);
    
    var userName = "testUserName1"; // or get it from Context.User.Identity.Name;

    // Try to get a List of existing user connections from the cache
    List<string> existingUserConnectionIds;
    ConnectedUsers.TryGetValue(userName, out existingUserConnectionIds);

    // happens on the very first connection from the user
    if(existingUserConnectionIds == null)
    {
        existingUserConnectionIds = new List<string>();
    }

    // First add to a List of existing user connections (i.e. multiple web browser tabs)
    existingUserConnectionIds.Add(Context.ConnectionId);

    
    // Add to the global dictionary of connected users
    ConnectedUsers.TryAdd(userName, existingUserConnectionIds);

    return base.OnConnected();
}

断开连接(关闭选项卡)时-从全局缓存字典中删除连接:

代码语言:javascript
运行
复制
public override Task OnDisconnected(bool stopCalled)
{
    var userName = Context.User.Identity.Name;

    List<string> existingUserConnectionIds;
    ConnectedUsers.TryGetValue(userName, out existingUserConnectionIds);

    // remove the connection id from the List 
    existingUserConnectionIds.Remove(Context.ConnectionId);

    // If there are no connection ids in the List, delete the user from the global cache (ConnectedUsers).
    if(existingUserConnectionIds.Count == 0)
    {
        // if there are no connections for the user,
        // just delete the userName key from the ConnectedUsers concurent dictionary
        List<string> garbage; // to be collected by the Garbage Collector
        ConnectedUsers.TryRemove(userName, out garbage);
    }

    return base.OnDisconnected(stopCalled);
}
票数 12
EN

Stack Overflow用户

发布于 2014-01-04 02:42:42

当客户端调用服务器端的函数时,您可以通过Context.ConnectionId检索它们的连接ID。现在,如果您希望通过集线器外部的机制访问该连接Id,您可以:

  1. 只是让集线器调用你的外部方法,传入连接id。
  2. 通过在OnConnected中添加字典并在OnDisconnected中从字典中删除来管理连接的客户端列表,也就是public static ConcurrentDictionary<string, MyUserType>...。一旦你有了用户列表,你就可以通过你的外部机制来查询它。

例1:

代码语言:javascript
运行
复制
public class MyHub : Hub
{
    public void AHubMethod(string message)
    {
        MyExternalSingleton.InvokeAMethod(Context.ConnectionId); // Send the current clients connection id to your external service
    }
}

示例2:

代码语言:javascript
运行
复制
public class MyHub : Hub
{
    public static ConcurrentDictionary<string, MyUserType> MyUsers = new ConcurrentDictionary<string, MyUserType>();

    public override Task OnConnected()
    {
        MyUsers.TryAdd(Context.ConnectionId, new MyUserType() { ConnectionId = Context.ConnectionId });
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        MyUserType garbage;

        MyUsers.TryRemove(Context.ConnectionId, out garbage);

        return base.OnDisconnected(stopCalled);
    }

    public void PushData(){
        //Values is copy-on-read but Clients.Clients expects IList, hence ToList()
        Clients.Clients(MyUsers.Keys.ToList()).ClientBoundEvent(data);
    }
}

public class MyUserType
{
    public string ConnectionId { get; set; }
    // Can have whatever you want here
}

// Your external procedure then has access to all users via MyHub.MyUsers

希望这能有所帮助!

票数 75
EN

Stack Overflow用户

发布于 2014-12-24 20:08:51

请允许我在重新连接上持不同意见。客户端仍在列表中,但connectid将更改。为了解决这个问题,我在重新连接时对静态列表进行了更新。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20908620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档