消息未到达 Azure SignalR 服务

Sam*_*Sam 5 azure signalr asp.net-core asp.net-core-signalr azure-signalr

我正在使用 React 前端在 ASP.NET Core 2.2 应用程序中实现 Azure SignalR 服务。当我发送消息时,我没有收到任何错误,但我的消息未到达 Azure SignalR 服务。

具体来说,这是一个私人聊天应用程序,因此当消息到达中心时,我只需将其发送给该特定聊天中的参与者,而不是发送给所有连接。

当我发送消息时,它会到达我的集线器,但我没有看到任何迹象表明该消息正在发送到 Azure 服务。

为了安全起见,我使用Auth0JWT Token身份验证。在我的中心,我正确地看到了授权用户声明,因此我认为不存在任何安全问题。正如我所提到的,我能够访问中心的事实告诉我,前端和安全性工作正常。

然而,在 Azure 门户中,我没有看到任何消息的迹象,但如果我正确读取数据,我确实会看到 2 个客户端连接,这在我的测试中是正确的,即我用于测试的两个打开的浏览器。这是一个屏幕截图:

在此输入图像描述

这是我的Startup.cs代码:

public void ConfigureServices(IServiceCollection services)
{
   // Omitted for brevity
   services.AddAuthentication(options => {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
   })
   .AddJwtBearer(jwtOptions => {
       jwtOptions.Authority = authority;
       jwtOptions.Audience = audience;

       jwtOptions.Events = new JwtBearerEvents
       {
            OnMessageReceived = context =>
            {
                var accessToken = context.Request.Query["access_token"];

                // Check to see if the message is coming into chat
                var path = context.HttpContext.Request.Path;
                if (!string.IsNullOrEmpty(accessToken) &&
                    (path.StartsWithSegments("/im")))
                {
                   context.Token = accessToken;
                }
                return System.Threading.Tasks.Task.CompletedTask;
             }
        };
    });


    // Add SignalR
    services.AddSignalR(hubOptions => {
       hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(10);
    }).AddAzureSignalR(Configuration["AzureSignalR:ConnectionString"]);
}
Run Code Online (Sandbox Code Playgroud)

这是Configure()方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
   // Omitted for brevity
   app.UseSignalRQueryStringAuth();

   app.UseAzureSignalR(routes =>
   {
      routes.MapHub<Hubs.IngridMessaging>("/im");
   });
}
Run Code Online (Sandbox Code Playgroud)

这是我用来将用户映射connectionId到的方法userName

public override async Task OnConnectedAsync()
{
    // Get connectionId
    var connectionId = Context.ConnectionId;

    // Get current userId
    var userId = Utils.GetUserId(Context.User);

    // Add connection
    var connections = await _myServices.AddHubConnection(userId, connectionId);

    await Groups.AddToGroupAsync(connectionId, "Online Users");
    await base.OnConnectedAsync();
}
Run Code Online (Sandbox Code Playgroud)

这是我的中心方法之一。请注意,我知道一个用户可能同时拥有多个连接。我只是简化了这里的代码以使其更容易理解。我的实际代码考虑了具有多个连接的用户:

[Authorize]
public async Task CreateConversation(Conversation conversation)
{
   // Get sender
   var user = Context.User;
   var connectionId = Context.ConnectionId;

   // Send message to all participants of this chat
   foreach(var person in conversation.Participants)
   {
       var userConnectionId = Utils.GetUserConnectionId(user.Id);
       await Clients.User(userConnectionId.ToString()).SendAsync("new_conversation", conversation.Message);
   }
}
Run Code Online (Sandbox Code Playgroud)

知道我做错了什么导致消息无法到达 Azure SignalR 服务吗?

Ita*_*cer 1

这可能是由于方法拼写错误、方法签名不正确、集线器名称不正确、客户端上的方法名称重复或客户端上缺少 JSON 解析器引起的,因为它可能在服务器上静默失败。

摘自客户端和服务器之间调用方法静默失败

方法拼写错误、方法签名不正确或中心名称不正确

如果被调用方法的名称或签名与客户端上的适当方法不完全匹配,则调用将失败。验证服务器调用的方法名称与客户端上的方法名称是否匹配。此外,SignalR 使用驼峰式方法创建集线器代理(这在 JavaScript 中是适用的),因此在服务器上调用的方法将在客户端代理中SendMessage调用。sendMessage如果您HubName在服务器端代码中使用该属性,请验证所使用的名称是否与在客户端上创建中心时使用的名称相匹配。如果您不使用该HubName属性,请验证 JavaScript 客户端中的中心名称是否采用驼峰式命名,例如 chatHub 而不是 ChatHub。

客户端上的方法名称重复

验证客户端上没有仅大小写不同的重复方法。如果您的客户端应用程序有一个名为 的方法sendMessage,请验证是否还有一个名为 的方法SendMessage

客户端缺少 JSON 解析器

SignalR 需要存在 JSON 解析器来序列化服务器和客户端之间的调用。如果您的客户端没有内置 JSON 解析器(例如 Internet Explorer 7),您需要在应用程序中包含一个。

更新

针对您的评论,我建议您尝试Azure SignalR示例之一,例如 SignalR 入门:聊天室示例,看看您是否获得相同的行为。

希望能帮助到你!