ASP.NET 2.2 Signalr Core 获取特定房间内所有参与者的连接ID

ASP.NET 2.2 Signalr Core Getting the connection Ids of all participants within a specific room

我想知道如何获取特定聊天室中所有参与者的所有连接 ID。目前,我能够将参与者的详细信息存储在聊天室中。但是,由于我无法手动设置 connectionIds,我如何确保下次他们重新加入房间时,消息会传递给他们?

另外,群的目的是什么?我该如何使用它?

ChatHub.cs

[Authorize]
    public class ChatHub : Hub
    {
        private readonly static ConnectionMapping<string> _connections = new ConnectionMapping<string>();
        private ChatSessionData chatSessionData;
        private ChatParticipantData chatParticipantData;
        private ChatMessageData chatMessageData;
        private ChatConnectionData chatConnectionData;

        public ChatHub(ChatSessionData chatSessionData, ChatConnectionData chatConnectionData, ChatParticipantData chatParticipantData, ChatMessageData chatMessageData)
        {
            this.chatSessionData = chatSessionData;
            this.chatParticipantData = chatParticipantData;
            this.chatMessageData = chatMessageData;
            this.chatConnectionData = chatConnectionData;
        }

        public async Task SendMessage(string user, string message)
        {
            var httpContext = Context.GetHttpContext();
            var SessionId = httpContext.Request.Query["SessionId"];
            var UserId = Context.User.Claims.Where(c => c.Type == "ChatSampleId").Select(c => c.Value).SingleOrDefault();
            var users = chatConnectionData.GetBySessionId(SessionId);
            List<string> connectionIds = new List<string>();
            if (users.Count > 0)
            {
                foreach (var item in users)
                {
                    connectionIds.Add(item.ConnectionId);
                }
                CreateChatMessageViewModel ccmvm = new CreateChatMessageViewModel
                {
                    Id = Guid.NewGuid().ToString(),
                    UserId = UserId,
                    SessionId = SessionId,
                    Name = user,
                    Message = message,
                    CreatedOn = DateTime.Now
                };
                chatMessageData.Save(ccmvm);
                //await Clients.All.SendAsync("ReceiveMessage",user, message);
                await Clients.Clients(connectionIds).SendAsync("ReceiveMessage", user, message);
            }

        }

        public async Task SessionNotification(string user, string message)
        {
            var httpContext = Context.GetHttpContext();
            var SessionId = httpContext.Request.Query["SessionId"];
            var UserId = Context.User.Claims.Where(c => c.Type == "ChatSampleId").Select(c => c.Value).SingleOrDefault();
            var users = chatConnectionData.GetBySessionId(SessionId);
            List<string> connectionIds = new List<string>();
            if (users.Count > 0)
            {
                foreach (var item in users)
                {
                    connectionIds.Add(item.ConnectionId);
                }
                connectionIds.Add(Context.ConnectionId);
            }
            else
            {
                connectionIds.Add(Context.ConnectionId);
            }
            //if only have one connectionid, send the message anyway
            await Clients.Clients(connectionIds).SendAsync("ReceiveMessage", user, message);
        }

        public override Task OnConnectedAsync()
        {
            var httpContext = Context.GetHttpContext();
            var SessionId = httpContext.Request.Query["SessionId"];
            var UserName = Context.User.Claims.Where(c => c.Type == "UserName").Select(c => c.Value).SingleOrDefault();
            var UserId = Context.User.Claims.Where(c => c.Type == "ChatSampleId").Select(c => c.Value).SingleOrDefault();
            var chatSession = chatParticipantData.GetBySessionIdAndUserId(SessionId, UserId);
            if (chatSession == null)
            {
                //New Connection
                CreateChatParticipantViewModel ccpvm = new CreateChatParticipantViewModel
                {
                    Id = Guid.NewGuid().ToString(),
                    SessionId = SessionId,
                    UserId = UserId
                };
                chatParticipantData.Save(ccpvm);
                CreateChatMessageViewModel ccmvm = new CreateChatMessageViewModel
                {
                    Id = Guid.NewGuid().ToString(),
                    UserId = UserId,
                    SessionId = SessionId,
                    Name = UserName,
                    Message = "has joined the conversation",
                    CreatedOn = DateTime.Now
                };
                chatMessageData.Save(ccmvm);
                SessionNotification(UserName, "has joined the conversation");
                CreateChatConnectionViewModel cccvm = new CreateChatConnectionViewModel
                {
                    Id = Guid.NewGuid().ToString(),
                    ConnectionId = Context.ConnectionId,
                    UserAgent = httpContext.Request.Headers["User-Agent"],
                    Connected = true,
                    SessionId = SessionId,
                    UserId = UserId,
                    CreatedOn = DateTime.Now
                };
                chatConnectionData.Save(cccvm);
                Groups.AddToGroupAsync(cccvm.ConnectionId, UserName);

            }
            else
            {
                var connectionDetails = chatConnectionData.GetBySessionIdAndUserId(SessionId, UserId);
                if (connectionDetails != null)
                {
                    //save the connectionId or Group details to the database and reload it
                    Groups.AddToGroupAsync(connectionDetails.ConnectionId, UserName);
                }
            }
            return base.OnConnectedAsync();
        }

        public override Task OnDisconnectedAsync(Exception exception)
        {
            return base.OnDisconnectedAsync(exception);
        }
    }

您问题的简短回答是... "what is the purpose of a group? And how do I use it?"

Groups in SignalR provide a method for broadcasting messages to specified subsets of connected clients. A group can have any number of clients, and a client can be a member of any number of groups

群详情请访问本官方link

注意:在您的情况下,可以使用群组来表示聊天室。

回答你的第二个问题... "how can I ensure that the next time they rejoin a room, that the messages are delivered to them?"

我相信您需要 maintain/persist 一个房间的聊天历史记录在持久存储中,比如在数据库中或者可能在您的 ChatHub 中(这取决于您的业务领域)。这样每次新用户加入或重新加入房间时 he/she 都可以看到该房间内的所有先前消息。 ChatHub 有责任向每个新加入的用户发送聊天记录。

问题的答案:“但是我如何确保加入房间的人会收到新消息?”

每当有人连接到 chatHub 时,您需要将他的 connectionId 存储在房间中,例如:

Groups.Add(Context.ConnectionId, "Your Chat Room Name");

将新用户添加到群组后,下次您在群组中广播消息时,新加入的用户也会收到该消息。像这样:

Clients.Group("Your chat room name").SendAsync("ReceiveMessage", user, message);

希望对您有所帮助。