5

I'm implementing Azure SignalR service in my ASP.NET Core 2.2 app with React front-end. When I send a message, I'm NOT getting any errors but my messages are not reaching the Azure SignalR service.

To be specific, this is a private chat application so when a message reaches the hub, I only need to send it to participants in that particular chat and NOT to all connections.

When I send a message, it hits my hub but I see no indication that the message is making it to the Azure Service.

For security, I use Auth0 JWT Token authentication. In my hub, I correctly see the authorized user claims so I don't think there's any issues with security. As I mentioned, the fact that I'm able to hit the hub tells me that the frontend and security are working fine.

In the Azure portal however, I see no indication of any messages but if I'm reading the data correctly, I do see 2 client connections which is correct in my tests i.e. two open browsers I'm using for testing. Here's a screen shot:

enter image description here

Here's my Startup.cs code:

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"]);
}

And here's the Configure() method:

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

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

Here's the method I use to map a user's connectionId to the 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();
}

Here's one of my hub methods. Please note that I'm aware a user may have multiple connections simultaneously. I just simplified the code here to make it easier to digest. My actual code accounts for users having multiple connections:

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

Any idea what I'm doing wrong that prevents messages from reaching the Azure SignalR service?

Sam
  • 26,817
  • 58
  • 206
  • 383
  • To troubleshoot, try sending a message to a known connection directly just to see if a message can go through. If it does then you can narrow down that chat logic to figure out what may be the issue. – Nkosi Dec 05 '18 at 13:15
  • I made sure that the message reaches the hub, invokes the correct method and sends the message to the correct ConnectionId. I still see 0 messages on the portal and nothing under "activity log". Other than the messages indicator under "Overview" tab and "Activity Log" on Azure portal, is there a way to see if the message is even reaching the Azure SignalR service? – Sam Dec 07 '18 at 19:15
  • The issue was caused by having the old version of client side scripts for SignalR. When I upgraded them to the latest version, everything started working fine. – Sam Dec 09 '18 at 05:58
  • This part looks wrong to me. But is probably not causing your issue. Looks like it is sending to the user that is requesting the call, not all of the participants // 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); } – Mike Dec 13 '18 at 22:01
  • Twice in my 3 months of using Azure's SignalR, the service has just completely stopped receiving messages (though it is still "running"). The SignalR service is called, messages get sent, that's for sure. But there is nothing logged on the signalR service in terms of reception. My solution has been to publish a new SignalR service and swap out the connection details. Not a workable long term solution. – blomster Mar 11 '22 at 17:28

1 Answers1

1

It might be caused by misspelled method, incorrect method signature, incorrect hub name, duplicate method name on the client, or missing JSON parser on the client, as it might fail silently on the server.

Taken from 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.

Update

In response to your comments, I would suggest you try one of the Azure SignalR samples, such as Get Started with SignalR: a Chat Room Example to see if you get the same behavior.

Hope it helps!

Itay Podhajcer
  • 2,616
  • 2
  • 9
  • 14
  • Thanks for the response but none of these suggestions applied to my code. Everything seems correct. Are you aware of a way to verify that a message is making it to the Azure SignalR service? I know that messages are hitting the hub and getting sent to active connectionId's. In other words, I verify the "SEND" part but not sure how I can verify that messages are "RECEIVED" or not "RECEIVED" at Azure SignalR service. – Sam Dec 07 '18 at 19:29
  • If one client receives a message from the second client, or alternately, clients receive messages from the hub (like when your `CreateConversation` is called), it means that the communication works. But why you are not seeing any values in the **Message Count (max)** counter is indeed strange. – Itay Podhajcer Dec 08 '18 at 16:14