Asp.net core 信号器-向特定用户发送消息
我正在学习Asp.net core 信号器-向特定用户发送消息,asp.net-core,signalr,Asp.net Core,Signalr,我正在学习SignalRMicrosoft教程 一切正常,但是,我想尝试更改ChatHub#SendMessage中的代码,以便向特定用户发送消息 所以我修改代码如下: public class ChatHub : Hub { public async Task SendMessage(string user, string message) { //await Clients.All.SendAsync("ReceiveMessage", u
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);
}
}
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(Context.UserIdentifier).SendAsync("ReceiveMessage", message);
}
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
}
但是,用户从未收到消息。只有在使用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();
}
但它似乎仍然没有发出信息
我做错了什么?我这样做的方式是,当用户登录时,我将他们添加到信号器组,该组是用户的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");
}
服务器端代码:
// 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");
}
有趣的是,当用户断开连接时,组自动消失。您不必维护正在创建的组
我知道这可能不是你想要的100%,但这是一个如何处理其他场景中类似情况的想法。我这样做的方式是当用户登录时,我将他们添加到信号器组中,该组是用户的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");
}
服务器端代码:
// 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");
}
有趣的是,当用户断开连接时,组自动消失。您不必维护正在创建的组
我知道这可能不是你想要的100%,但这是一个如何处理其他场景中类似情况的想法。我发现了这个问题。我在Clients.user(user.SendAsync
调用中省略了user参数
所以它应该是这样的:
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);
}
}
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(Context.UserIdentifier).SendAsync("ReceiveMessage", message);
}
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
}
公共异步任务发送消息(字符串用户,字符串消息)
{
//等待Clients.All.SendAsync(“ReceiveMessage”,user,message);
wait Clients.User(User).SendAsync(“ReceiveMessage”,User,message);//我发现了问题。我在Clients.User(User).SendAsync调用中省略了用户参数
所以它应该是这样的:
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);
}
}
public async Task SendMessage(string user, string message)
{
//await Clients.All.SendAsync("ReceiveMessage", user, message);
await Clients.User(Context.UserIdentifier).SendAsync("ReceiveMessage", message);
}
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
}
公共异步任务发送消息(字符串用户,字符串消息)
{
//等待Clients.All.SendAsync(“ReceiveMessage”,user,message);
等待Clients.User(User).SendAsync(“ReceiveMessage”,User,message);//你看过了吗?@Andy-谢谢你的链接,我确实看过了。但是,不幸的是,这不是dotnet core的。啊,糟糕……我讨厌这样。但其中一些可能会转移。我会补充一个关于我如何处理基于组的用户的答案。也许以后会有用。你看过了吗?@Andy-谢谢你的链接,我看过了看看这个。然而,不幸的是,它不是为dotnet core设计的。啊,糟糕。我讨厌它。但其中一些可能会转移。我将添加一个关于我如何处理基于组的用户的答案。也许这在以后可能会有用。非常感谢你提供的信息,我可能会在某个时候使用这个想法。非常感谢你提供的信息,我可能最终会使用这个想法有一点。