邮件不通过Azure SignalR服务

时间:2018-12-05 04:21:31

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

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

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

当我发送一条消息时,它击中了我的集线器,但是我看不到该消息正在将其发送到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服务吗?

1 个答案:

答案 0 :(得分:1)

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

取自Calling methods between the client and server silently fails

  

方法拼写错误,方法签名错误或中心名称错误

     

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

     

客户端上的方法名称重复

     

验证您的客户端上没有重复的方法(仅因大小写而异)。如果您的客户端应用程序具有一种名为sendMessage的方法,请确认还没有一种名为SendMessage的方法。

     

客户端上缺少JSON解析器

     

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

更新

为回应您的评论,建议您尝试使用 Azure SignalR 示例之一,例如 Get Started with SignalR: a Chat Room Example,以查看是否获得相同的行为。

希望有帮助!