【问题标题】:ASP.NET 2.2 Signalr Core Getting the connection Ids of all participants within a specific roomASP.NET 2.2 Signalr Core 获取特定房间内所有参与者的连接 ID
【发布时间】:2019-06-20 03:20:47
【问题描述】:

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

另外,组的目的是什么?以及如何使用它?

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);
        }
    }

【问题讨论】:

  • 当您查找数据时,您确定重新连接时 SessionId 和 UserId 都没有改变吗? SessionId 有点尖叫它可能会有所不同。
  • Session Id 就是聊天室的Id,和它一样。我刚刚意识到我需要知道如何获取该房间/组中的用户列表及其当前的连接 ID。我无法存储 connectionId,因为它每次都不同,并且无法手动分配。
  • 我想我要问的是如何获取房间内的连接 ID 列表?组的目的是什么?我不明白。
  • 请更新您的问题描述。目前尚不清楚它现在的行为方式以及您现在的实际期望。
  • 完成了。感谢阅读。

标签: c# asp.net sockets asp.net-core signalr


【解决方案1】:

对您的问题的简短回答是......“组的目的是什么?我如何使用它?”

SignalR 中的组提供了一种将消息广播到指定连接客户端子集的方法。一个组可以有任意数量的客户端,一个客户端可以是任意数量的组的成员

群详情请关注本官link

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

回答您的第二个问题...“我如何确保他们下次重新加入房间时,消息会发送给他们?”

我相信您需要在数据库或您的 ChatHub 中(这取决于您的业务领域)中的持久存储中维护/保留房间的聊天历史记录。这样每次新用户加入或重新加入房间时,他/她都可以看到该房间内所有以前的消息。 ChatHub 负责将聊天记录发送给每个新加入的用户。

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

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

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

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

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

希望这会有所帮助。

【讨论】:

  • 嗨!感谢回复。问题是,我已经在聊天室中保留了历史记录。但是我如何确保加入房间的人会收到新消息?是通过群组吗?目前我尝试存储 connectionId 但这不起作用,因为我无法手动将其分配给用户
  • @JianYA,我已经更新了答案。我还建议您阅读 SignalR 官方文档,以充分了解 SignalR 集线器如何维护 Groups 和 ConnectionIds 以及它们的实际工作方式。
  • 我会这样做的。感谢您迄今为止的帮助。
  • 什么意思?我是否将索引更改为 Context.ConnectionId?
猜你喜欢
  • 2019-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多