Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 信号2:OnDisconnected在页面刷新时立即触发_C#_Asp.net_Signalr - Fatal编程技术网

C# 信号2:OnDisconnected在页面刷新时立即触发

C# 信号2:OnDisconnected在页面刷新时立即触发,c#,asp.net,signalr,C#,Asp.net,Signalr,OnDisconnect方法在被激发之前不是应该等待默认的30秒吗?对我来说,它会在页面刷新时立即启动(F5) 我有一个User对象,它跟踪hashset中的用户连接 在我的中心,我有一本字典来跟踪连接的用户 OnConnected:我将该用户添加到字典中,如果该用户已经存在,我只需将另一个connectionid添加到用户hashset中 OnDisconnected:我从调用用户hashset中删除该connectionId,如果他没有任何连接,我从字典中删除用户对象 我需要跟踪用户对象,并

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

我有一个User对象,它跟踪hashset中的用户连接

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

OnConnected:我将该用户添加到字典中,如果该用户已经存在,我只需将另一个connectionid添加到用户hashset中

OnDisconnected:我从调用用户hashset中删除该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();
    }
私有静态只读ConcurrentDictionary用户
=新的ConcurrentDictionary();
已连接的公用覆盖任务(){
字符串userName=Context.User.Identity.Name;
字符串connectionId=Context.connectionId;
var user=Users.GetOrAdd(用户名,\=>newuser{
Name=用户名,
connectionId=newhashset()
});
锁(user.connectionId){
user.connectionId.Add(connectionId);
//TODO:广播连接的用户
}
返回base.OnConnected();
}
公共覆盖任务OnDisconnected(){
字符串userName=Context.User.Identity.Name;
字符串connectionId=Context.connectionId;
用户;
Users.TryGetValue(用户名,out user);
如果(用户!=null){
锁(user.connectionId){
user.connectionId.RemoveWhere(cid=>cid.Equals(connectionId));
如果(!user.connectionId.Any()){
用户删除用户;
Users.TryRemove(用户名,out-removedUser);
//您可能只希望在以下情况下广播此信息:
//是用户的最后一个连接,并且用户是实际的
//现在已断开所有连接。
Clients.Others.userDisconnected(用户名);
}
}
}
返回base.OnDisconnected();
}

所以我解决了这个问题,在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);
                    }
                }
            }
        }

当您刷新页面时,基本上就是离开页面,导致断开连接。为什么您认为它会“等待”30秒?DisconnectTimeout-表示在引发disconnect事件之前,连接断开后等待的时间量。默认值为30秒。