azure - 消息未到达 Azure SignalR 服务

标签 azure asp.net-core signalr asp.net-core-signalr azure-signalr

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

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

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

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

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

enter image description here

这是我的 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"]);
}

这是 Configure() 方法:

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

   app.UseAzureSignalR(routes =>
   {
      routes.MapHub<Hubs.IngridMessaging>("/im");
   });
}

这是我用来将用户的 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();
}

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

[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);
   }
}

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

最佳答案

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

取自 Calling methods between the client and server silently fails :

Misspelled method, incorrect method signature, or incorrect hub name

If the name or signature of a called method does not exactly match an appropriate method on the client, the call will fail. Verify that the method name called by the server matches the name of the method on the client. Also, SignalR creates the hub proxy using camel-cased methods, as is appropriate in JavaScript, so a method called SendMessage on the server would be called sendMessage in the client proxy. If you use the HubName attribute in your server-side code, verify that the name used matches the name used to create the hub on the client. If you do not use the HubName attribute, verify that the name of the hub in a JavaScript client is camel-cased, such as chatHub instead of ChatHub.

Duplicate method name on client

Verify that you do not have a duplicate method on the client that differs only by case. If your client application has a method called sendMessage, verify that there isn't also a method called SendMessage as well.

Missing JSON parser on the client

SignalR requires a JSON parser to be present to serialize calls between the server and the client. If your client doesn't have a built-in JSON parser (such as Internet Explorer 7), you'll need to include one in your application.

更新

为了回应您的评论,我建议您尝试 Azure SignalR 示例之一,例如 Get Started with SignalR: a Chat Room Example看看您是否有相同的行为。

希望对你有帮助!

关于azure - 消息未到达 Azure SignalR 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53625138/

相关文章:

javascript - 连接开始后连接到 SignalR Hub

Azure AD 无法与 spring-boot webflux 配合使用

c# - Azure 计算模拟器无法启动。代理因错误而崩溃(连续)

azure - 如何在ARM模板中引用静态IP地址?

Azure 警报不起作用

c# - 具有自定义名称的 MVC APIController

c# - ASP.Net JSON 配置文件用数组转换

android - SignalR - 当应用程序处于后台甚至被杀死时通知消息

c# - 在 ASP.NET Core 中添加数据库驱动的调度程序的正确位置是什么?

javascript - SignalR JavaScript 客户端通用触发器