Quản lý người dùng và nhóm trong SignalR
Tác giả: Brennan Conroy
SignalR (thư viện giao tiếp thời gian thực) cho phép gửi tin nhắn đến tất cả kết nối liên kết với một người dùng cụ thể và đến các nhóm kết nối có tên.
Người dùng trong SignalR
Một người dùng duy nhất trong SignalR có thể có nhiều kết nối đến một ứng dụng. Ví dụ, người dùng có thể kết nối trên máy tính để bàn cũng như trên điện thoại. Mỗi thiết bị có một kết nối SignalR riêng biệt, nhưng tất cả đều được liên kết với cùng một người dùng. Nếu một tin nhắn được gửi đến người dùng, tất cả các kết nối liên kết với người dùng đó đều nhận được tin nhắn. Định danh người dùng (user identifier) cho một kết nối có thể được truy cập thông qua thuộc tính Context.UserIdentifier trong hub.
Mặc định, SignalR sử dụng ClaimTypes.NameIdentifier từ ClaimsPrincipal liên kết với kết nối làm định danh người dùng. Để tùy chỉnh hành vi này, xem Use claims to customize identity handling.
Gửi tin nhắn đến một người dùng cụ thể bằng cách truyền định danh người dùng vào hàm User trong một phương thức hub, như minh họa trong ví dụ sau:
Lưu ý: Định danh người dùng (user identifier) phân biệt chữ hoa và chữ thường.
public Task SendPrivateMessage(string user, string message)
{
return Clients.User(user).SendAsync("ReceiveMessage", message);
}Nhóm trong SignalR
Một nhóm (group) là tập hợp các kết nối liên kết với một tên. Tin nhắn có thể được gửi đến tất cả kết nối trong một nhóm. Nhóm là cách được khuyến nghị để gửi đến một kết nối hoặc nhiều kết nối vì các nhóm được quản lý bởi ứng dụng. Một kết nối có thể là thành viên của nhiều nhóm. Nhóm lý tưởng cho các tình huống như ứng dụng chat, trong đó mỗi phòng có thể được biểu diễn như một nhóm.
Thêm hoặc xóa kết nối khỏi nhóm
Các kết nối được thêm vào hoặc xóa khỏi nhóm thông qua các phương thức AddToGroupAsync và RemoveFromGroupAsync:
public async Task AddToGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has joined the group {groupName}.");
}
public async Task RemoveFromGroup(string groupName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has left the group {groupName}.");
}Việc thêm một người dùng vào nhóm nhiều lần là an toàn, không có ngoại lệ nào được ném ra trong trường hợp người dùng đã có trong nhóm.
Tư cách thành viên nhóm (group membership) không được lưu giữ khi kết nối kết nối lại. Kết nối cần tham gia lại nhóm khi nó được thiết lập lại. Không thể đếm số thành viên của một nhóm, vì thông tin này không có sẵn nếu ứng dụng được scale ra nhiều server.
Các nhóm được lưu trong bộ nhớ, vì vậy chúng sẽ không tồn tại qua quá trình khởi động lại server. Hãy xem xét Azure SignalR Service cho các tình huống yêu cầu tư cách thành viên nhóm phải được lưu trữ lâu dài. Để biết thêm thông tin, xem Azure SignalR.
Để bảo vệ quyền truy cập tài nguyên khi sử dụng nhóm, hãy sử dụng chức năng authentication và authorization trong ASP.NET Core. Nếu người dùng chỉ được thêm vào nhóm khi thông tin xác thực hợp lệ cho nhóm đó, tin nhắn gửi đến nhóm sẽ chỉ đến các người dùng được ủy quyền. Tuy nhiên, nhóm không phải là tính năng bảo mật. Authentication claims (xác nhận quyền xác thực) có các tính năng mà nhóm không có, chẳng hạn như hết hạn và thu hồi. Nếu quyền truy cập của người dùng vào nhóm bị thu hồi, ứng dụng phải xóa người dùng khỏi nhóm một cách rõ ràng.
Lưu ý: Tên nhóm phân biệt chữ hoa và chữ thường.