signalR2:打开断开连接在页面刷新时立即触发

本文关键字:刷新 断开 连接 signalR2 | 更新日期: 2023-09-27 18:30:41

OnDisconnect 方法不应该在被触发之前等待默认的 30 秒吗?对我来说,它会在页面刷新(F5)时立即触发。

我有一个 User 对象,它跟踪哈希集中的用户连接。

在我的中心,我有一个字典来跟踪连接的用户。

OnConnected:我将该用户添加到字典中,如果用户已经在那里,我只需将另一个连接ID添加到用户哈希集中。

OnDisconnected:我从调用用户的哈希集中删除了该connectionId,如果他没有任何连接,我会从字典中删除用户对象。

我需要跟踪用户对象,并且在每次页面刷新(F5)时都会丢失它,因为OnDisconnected会立即触发并删除用户仅连接和对象。当页面再次加载时,会创建一个新的用户对象,因为旧的用户对象会立即被删除。

我的实现看起来像这样

  private static readonly ConcurrentDictionary<string, User> Users 
        = new ConcurrentDictionary<string, User>();
    public override Task OnConnected() {
        string userName = Context.User.Identity.Name;
        string connectionId = Context.ConnectionId;
        var user = Users.GetOrAdd(userName, _ => new User {
            Name = userName,
            ConnectionIds = new HashSet<string>()
        });
        lock (user.ConnectionIds) {
            user.ConnectionIds.Add(connectionId);
            // TODO: Broadcast the connected user
        }
        return base.OnConnected();
        }
        public override Task OnDisconnected() {
        string userName = Context.User.Identity.Name;
        string connectionId = Context.ConnectionId;
        User user;
        Users.TryGetValue(userName, out user);
        if (user != null) {
            lock (user.ConnectionIds) {
                user.ConnectionIds.RemoveWhere(cid => cid.Equals(connectionId));
                if (!user.ConnectionIds.Any()) {
                    User removedUser;
                    Users.TryRemove(userName, out removedUser);
                    // You might want to only broadcast this info if this 
                    // is the last connection of the user and the user actual is 
                    // now disconnected from all connections.
                    Clients.Others.userDisconnected(userName);
                }
            }
        }
        return base.OnDisconnected();
    }

signalR2:打开断开连接在页面刷新时立即触发

因此,

我通过在 OnDisconnected 方法中运行一个任务并将该方法延迟 x 秒,然后检查用户是否已重新连接,如果他没有将他从列表中删除,那么我解决了这个问题。

public override Task OnDisconnected(bool stopCalled)
        {
                Task mytask = Task.Run(() =>
                {
                    UserDisconnected(Context.User.Identity.Name, Context.ConnectionId);
                });

            return base.OnDisconnected(stopCalled);
        }

private async void UserDisconnected(string un, string cId)
        {
            await Task.Delay(10000);
            string userName = un;
            string connectionId = cId;
            User user;
            enqueuedDictionary.TryGetValue(userName, out user);
            if (user != null)
            {
                lock (user.ConnectionIds)
                {
                    user.ConnectionIds.RemoveWhere(cid => cid.Equals(connectionId));
                    if (!user.ConnectionIds.Any())
                    {
                        User removedUser;
                        enqueuedDictionary.TryRemove(userName, out removedUser);
                        ChatSession removedChatSession;
                        groupChatSessions.TryRemove(userName, out removedChatSession);
                        UpdateQ(removedUser.QPos);
                    }
                }
            }
        }