Сообщения, не поступающие в службу Azure SignalR

Я реализую службу Azure SignalR в своем приложении ASP.NET Core 2.2 с интерфейсом React. Когда я отправляю сообщение, я НЕ получаю никаких ошибок, но мои сообщения не доходят до службы Azure SignalR.

Чтобы быть конкретным, это приложение для частного чата, поэтому, когда сообщение достигает хаба, мне нужно только отправить его участникам этого конкретного чата, а НЕ всем соединениям.

Когда я отправляю сообщение, оно попадает в мой концентратор, но я не вижу никаких признаков того, что сообщение попадает в службу Azure.

В целях безопасности я использую аутентификацию Auth0 JWT 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"]);
}

А вот и метод 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?


person Sam    schedule 05.12.2018    source источник
comment
Чтобы устранить неполадки, попробуйте отправить сообщение в известное соединение напрямую, чтобы проверить, может ли оно пройти. Если это так, вы можете сузить логику чата, чтобы выяснить, в чем может быть проблема.   -  person Nkosi    schedule 05.12.2018
comment
Я убедился, что сообщение достигает концентратора, вызывает правильный метод и отправляет сообщение на правильный ConnectionId. Я по-прежнему вижу 0 сообщений на портале и ничего в журнале активности. Есть ли способ, кроме индикатора сообщений на вкладке «Обзор» и журнала активности на портале Azure, узнать, доходит ли сообщение до службы Azure SignalR?   -  person Sam    schedule 07.12.2018
comment
Проблема была вызвана наличием старой версии клиентских скриптов для SignalR. Когда я обновил их до последней версии, все стало нормально работать.   -  person Sam    schedule 09.12.2018
comment
Мне эта часть кажется неправильной. Но, вероятно, это не вызывает вашей проблемы. Похоже, он отправляется пользователю, который запрашивает звонок, а не всем участникам // Отправить сообщение всем участникам этого чата foreach (var person in chat.Participants) {var userConnectionId = Utils.GetUserConnectionId (user.Id) ; ждать Clients.User (userConnectionId.ToString ()). SendAsync (new_conversation, диалог.Message); }   -  person Mike    schedule 14.12.2018


Ответы (1)


Это может быть вызвано ошибкой в ​​написании метода, неправильной сигнатурой метода, неправильным именем концентратора, дублированием имени метода на клиенте или отсутствием парсера JSON на клиенте, так как на сервере может произойти сбой без уведомления.

Взято из Тихий вызов методов между клиентом и сервером не работает:

Метод с ошибкой написания, неправильная подпись метода или неправильное имя концентратора

Если имя или подпись вызываемого метода не совсем соответствует подходящему методу на клиенте, вызов завершится ошибкой. Убедитесь, что имя метода, вызванного сервером, совпадает с именем метода на клиенте. Кроме того, SignalR создает прокси-сервер концентратора, используя методы с верблюжьей структурой, как это принято в JavaScript, поэтому метод с именем SendMessage на сервере будет вызываться sendMessage в прокси-сервере клиента. Если вы используете атрибут HubName в коде на стороне сервера, убедитесь, что используемое имя совпадает с именем, используемым для создания концентратора на клиенте. Если вы не используете атрибут HubName, убедитесь, что имя концентратора в клиенте JavaScript имеет верблюжий регистр, например chatHub вместо ChatHub.

Повторяющееся название метода на клиенте

Убедитесь, что у вас нет повторяющегося метода на клиенте, который отличается только регистром. Если в вашем клиентском приложении есть метод с именем sendMessage, убедитесь, что также нет метода с именем SendMessage.

На клиенте отсутствует парсер JSON

SignalR требует наличия парсера JSON для сериализации вызовов между сервером и клиентом. Если у вашего клиента нет встроенного анализатора JSON (например, Internet Explorer 7), вам необходимо включить его в свое приложение.

Обновить

В ответ на ваши комментарии я предлагаю вам попробовать один из примеров Azure SignalR, например Приступите к работе с SignalR: пример чата, чтобы проверить, получится ли у вас такое же поведение.

Надеюсь, это поможет!

person Itay Podhajcer    schedule 05.12.2018
comment
Спасибо за ответ, но ни одно из этих предложений не применимо к моему коду. Вроде все правильно. Знаете ли вы, как проверить, что сообщение попадает в службу Azure SignalR? Я знаю, что сообщения попадают в концентратор и отправляются на активные идентификаторы подключения. Другими словами, я проверяю часть ОТПРАВИТЬ, но не знаю, как я могу проверить, ПОЛУЧАЮТСЯ или нет сообщения в службе Azure SignalR. - person Sam; 07.12.2018
comment
Если один клиент получает сообщение от второго клиента или, наоборот, клиенты получают сообщения от концентратора (например, когда вызывается ваш CreateConversation), это означает, что связь работает. Но почему вы не видите никаких значений в счетчике Message Count (max), действительно странно. - person Itay Podhajcer; 08.12.2018