signalR - 向特定用户发送消息
signalR - send message to specific user
我正在学习位于 here 的 SignalR
Microsoft 教程。
一切正常,但是,我想尝试更改 ChatHub#SendMessage
中的代码以向特定用户发送消息。
所以我修改了这样的代码:
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(user).SendAsync("ReceiveMessage", message);
}
}
但是,用户从未收到消息。仅当您使用 Clients.All.SendAsync
(即上面注释掉的行)时才会发送消息。
我还进行了更多研究,并从 中发现我可能需要实施自定义用户提供程序。所以我实现了一个:
public class CustomUserIdProvider : IUserIdProvider
{
public string GetUserId(HubConnectionContext connection)
{
return "user1";
}
}
然后在Startup.cs
,我注册了这个供应商:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
services.AddSignalR();
}
然后我尝试在发送消息时使用Context.UserIdentifier
,像这样:
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(Context.UserIdentifier).SendAsync("ReceiveMessage", message);
}
但是好像还是发不出去
我做错了什么?
我的做法是当用户登录时将他们添加到 SignalR 组,该组是用户的 ID 或名称。这样,它就是一个用户的唯一组。然后我将消息发送到该组。只有该用户会收到该消息,因为他们是该组中唯一的用户。
客户端代码:
// Optional: authenticate with a server, get a token... or send username/password in following request
_hub = new HubConnectionBuilder()
.WithUrl(_envSettings.CreatePlayerServiceHubPath(), x =>
{
x.Headers.Add("x-lcc-version", AppEnvironment.Application.Version);
x.Headers.Add("x-lcc-username", username);
x.Headers.Add("x-lcc-authorization", token);
})
.AddNewtonsoftJsonProtocol()
.Build();
_hub.Closed += OnSignalRDisconnectedFromServerAsync;
SetupRPCs();
await _hub.StartAsync().ConfigureAwait(false);
服务器端代码:
public override async Task OnConnectedAsync()
{
var userName = Context.GetHttpContext().Request.Headers["x-lcc-username"];
var token = Context.GetHttpContext().Request.Headers["x-lcc-authorization"];
// Optional: validate authorization
await Groups.AddToGroupAsync(Context.ConnectionId, userName);
// Then when you want to send a message to the user:
await Clients.Group(userName).SendAsync("hello", "world");
}
很棒的是,当用户断开连接时,Group
会自动消失。您不必维护您正在创建的那些组。
我知道这可能不是您要找的 100%,但它是关于如何处理与其他场景类似的情况的想法。
我发现了问题。我在 Clients.User(user).SendAsync
调用中省略了用户参数。
所以应该是这样的:
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(user).SendAsync("ReceiveMessage", user, message); // <-- add user parameter
}
我正在学习位于 here 的 SignalR
Microsoft 教程。
一切正常,但是,我想尝试更改 ChatHub#SendMessage
中的代码以向特定用户发送消息。
所以我修改了这样的代码:
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(user).SendAsync("ReceiveMessage", message);
}
}
但是,用户从未收到消息。仅当您使用 Clients.All.SendAsync
(即上面注释掉的行)时才会发送消息。
我还进行了更多研究,并从
public class CustomUserIdProvider : IUserIdProvider
{
public string GetUserId(HubConnectionContext connection)
{
return "user1";
}
}
然后在Startup.cs
,我注册了这个供应商:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
services.AddSignalR();
}
然后我尝试在发送消息时使用Context.UserIdentifier
,像这样:
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(Context.UserIdentifier).SendAsync("ReceiveMessage", message);
}
但是好像还是发不出去
我做错了什么?
我的做法是当用户登录时将他们添加到 SignalR 组,该组是用户的 ID 或名称。这样,它就是一个用户的唯一组。然后我将消息发送到该组。只有该用户会收到该消息,因为他们是该组中唯一的用户。
客户端代码:
// Optional: authenticate with a server, get a token... or send username/password in following request
_hub = new HubConnectionBuilder()
.WithUrl(_envSettings.CreatePlayerServiceHubPath(), x =>
{
x.Headers.Add("x-lcc-version", AppEnvironment.Application.Version);
x.Headers.Add("x-lcc-username", username);
x.Headers.Add("x-lcc-authorization", token);
})
.AddNewtonsoftJsonProtocol()
.Build();
_hub.Closed += OnSignalRDisconnectedFromServerAsync;
SetupRPCs();
await _hub.StartAsync().ConfigureAwait(false);
服务器端代码:
public override async Task OnConnectedAsync()
{
var userName = Context.GetHttpContext().Request.Headers["x-lcc-username"];
var token = Context.GetHttpContext().Request.Headers["x-lcc-authorization"];
// Optional: validate authorization
await Groups.AddToGroupAsync(Context.ConnectionId, userName);
// Then when you want to send a message to the user:
await Clients.Group(userName).SendAsync("hello", "world");
}
很棒的是,当用户断开连接时,Group
会自动消失。您不必维护您正在创建的那些组。
我知道这可能不是您要找的 100%,但它是关于如何处理与其他场景类似的情况的想法。
我发现了问题。我在 Clients.User(user).SendAsync
调用中省略了用户参数。
所以应该是这样的:
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(user).SendAsync("ReceiveMessage", user, message); // <-- add user parameter
}