ASP.NET 2.2 Signalr Core Получение идентификаторов подключения всех участников в определенной комнате - PullRequest
0 голосов
/ 26 января 2019

Я хотел бы знать, как получить все идентификаторы соединений всех участников в определенной комнате чата. В настоящее время я могу хранить данные участников в чате. Однако, поскольку я не могу вручную установить идентификаторы соединения, как я могу гарантировать, что в следующий раз, когда они вернутся в комнату, сообщения будут доставлены им?

Кроме того, какова цель группы? И как мне это использовать?

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

1 Ответ

0 голосов
/ 26 января 2019

Короткий ответ на ваш вопрос: «Какова цель группы? И как мне ее использовать?»

Группы в SignalR предоставляют метод для рассылки сообщений указанным подмножествам подключенных клиентов. Группа может иметь любое количество клиентов, а клиент может быть членом любого количества групп

Для получения подробной информации о группе, пожалуйста, посетите эту официальную ссылку

Примечание. В вашем случае группу можно использовать для представления комнаты чата.

Ответьте на ваш второй вопрос ... «Как я могу гарантировать, что в следующий раз, когда они вернутся в комнату, что сообщения будут доставлены им?»

Я считаю, что вам нужно поддерживать / сохранять историю чатов комнаты в постоянном хранилище, например, в базе данных или, возможно, в вашем ChatHub (это зависит от вашего бизнес-домена). Таким образом, каждый раз, когда новый пользователь присоединяется к комнате или присоединяется к ней, он / она может видеть все предыдущие сообщения в этой комнате. ChatHub будет обязан отправлять историю чата каждому новому присоединяющемуся пользователю.

Ответ на вопрос: «Но как мне гарантировать, что человек, присоединяющийся к комнате, получит новые сообщения?»

Всякий раз, когда человек подключается к ChatHub, вам необходимо сохранить его соединение с номером комнаты, например:

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

Как только новый пользователь добавлен в группу, при следующей трансляции сообщения в группе вновь присоединенный пользователь также получит сообщение. Вот так:

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

Надеюсь, это поможет.

...