Abh*_*eet 8 c# azure signalr azure-signalr
使用Azure SignalR(不是 .Net Core SignalR),是否Clients.Users.SendAsync支持向特定用户发送消息?
[Authorize]
public class ChatHub : Hub
{
public async Task OnNewMessage(string userId, string message)
{
await Clients.Users(userId)
//Does Azure SignalR supports sending message to specific user,
// the way .Net Core SignalR does it
.SendAsync("OnNewMessage", userId, message);
}
}
Run Code Online (Sandbox Code Playgroud)
如果是,Asp.Net Identity Claims Principal 如何传递给 Azure SignalR?
编辑:2021 年 6 月 18 日
以下回复并未解决这些问题。抱歉,我已经按照文档进行了自定义UserIdBasedProvider等。我想强调一下 -
这个问题与 SignalR 的处理方式有关
.Users(<*some-user-id*>).Send();
理想情况下,我们会
.Client(<connection id>).Send()向特定用户发送消息。但是对于这种架构,我们必须自己将 userId 和 connectionId 存储在 DB 等中。
.User(userId).Send()与 .Net Core SignalR 完美配合。所以我相信 SignalR SDK 一定在内存中保存了每个连接 ID 和用户 ID 的映射。
Azure SignalR 是否在内部跟踪 UserId、Connection Id 映射并发送消息?
是的,如果您想实现无服务器架构,您应该使用 Azure Functions。典型的无服务器架构如下所示
客户端(即浏览器)向 azure 函数发送协商请求,响应包含与 建立连接所需的所有信息Azure SignalR。您应该将 JWT 令牌附加到协商请求中。如何获取 JWT 令牌取决于您。连接它非常简单,只需在创建 signalR 连接时提供一个令牌工厂即可
const connection = new signalR.HubConnectionBuilder()
.withUrl('link to your azure functions api', {
accessTokenFactory: () => {
return 'your token'
}
})
.build();
Run Code Online (Sandbox Code Playgroud)
为此,您还需要设置上游连接,以便您的Azure SignalR服务可以将所有事件转发到 Azure Function。Azure SignalRAzure 函数处理上游事件并向一个或多个用户发送请求以广播数据。
SendMessage除了 Azure 函数绑定之外,a 中方法的代码hub与常规集线器非常相似。您还需要扩展ServerlessHub类而不是Hub安装Microsoft.Azure.WebJobs.Extensions.SignalRService包
public class ChatHub : ServerlessHub
{
[FunctionName(nameof(SendToUser))]
public async Task SendToUser([SignalRTrigger] InvocationContext invocationContext, string userName, string message)
{
await Clients.User(userName).SendAsync("new_message", new NewMessage(invocationContext, message));
}
[FunctionName("negotiate")]
public SignalRConnectionInfo Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req)
{
var claims = GetClaims(req.Headers["Authorization"]);
var userName = claims.First(x => x.Type == ClaimTypes.NameIdentifier);
return Negotiate(userName.Value, claims);
}
private class NewMessage
{
public string ConnectionId { get; }
public string Sender { get; }
public string Text { get; }
public NewMessage(InvocationContext invocationContext, string message)
{
Sender = string.IsNullOrEmpty(invocationContext.UserId) ? string.Empty : invocationContext.UserId;
ConnectionId = invocationContext.ConnectionId;
Text = message;
}
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以在此处找到包含分步说明的代码示例
如果您不想完全无服务器并且想使用常规网络应用程序,那么也完全没问题。架构图看起来像这样
在这种情况下,您应该使用常规的集线器类。您发布的代码应该可以正常工作。
连接管理完全由 Azure Signalr 服务完成,您不需要执行任何额外的同步,也不需要将连接数据存储在数据库中。只需设置层大小和单位数量即可。
以下是其工作原理的简短描述:
negotiate,并接收到 azure signalr 服务的链接和访问令牌。这是一个 JWT 令牌。JWT 令牌由几个部分组成。该令牌的第二部分是有效负载,其中包含声明。negotiate连接到 azure signalr 服务。因此,Azure SignalR 服务使用从协商端点接收的此访问令牌来对用户进行身份验证。您不必编写任何额外的代码,因为这一切都是由库在幕后完成的。
如果您使用 Web 应用程序,请求negotiate将由 SignalR Sdk 处理,您无需为此编写任何额外代码。
这一切都在这篇文章中描述了
| 归档时间: |
|
| 查看次数: |
441 次 |
| 最近记录: |