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);
希望对您有所帮助。
我想知道如何获取特定聊天室中所有参与者的所有连接 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);
希望对您有所帮助。