Signalr-Redis "Нет связи с этим ID" - PullRequest
0 голосов
/ 05 июня 2019

Фон

У меня есть веб-сайт, который развернут в облаке Google. Этот сайт написан с использованием ядра asp.net (v2.2) и сигнализатора.

Моя архитектура приложения такова, что у меня есть две машины под управлением Linux, которые обслуживают один и тот же сайт. Сайт обслуживается Kastrel (localhost) и оборачивается nginx (для внешней сети). У меня есть облачный балансировщик нагрузки, который разделяет трафик между этими двумя экземплярами. LB, определенный для разделения трафика по схожести сеанса.

Я определил, что SignalR должен использовать Redis, чтобы хорошо работать в среде с несколькими экземплярами.

Мой startup.cs код:

var redisCs = ConfigurationOptions.Parse("REDIS CS");
services.AddSignalR().AddRedis(options =>
{
    options.ConnectionFactory = async writer =>
    {
        var connection = await ConnectionMultiplexer.ConnectAsync(redisCs, writer);
        return connection;
    };
    options.Configuration.ClientName = "Main-website-Signalr";
});

Проблема

Когда я тестирую его, иногда он работает, а в другой - нет.

Когда это не удалось, я вижу эти журналы на консоли браузера:

WebSocket connection to 'wss://mysite.com/hubs/myhub?id=R_Zmaew-lRN_r2d_c-xOyg' failed: Error during WebSocket handshake: Unexpected response code: 404

На вкладке «Сеть» в моем браузере я вижу, что браузер пытается связаться с адресом wss://mysite.com/hubs/myhub?id=R_Zmaew-lRN_r2d_c-xOyg и получает ответ 404.

Мое расследование

Я беспокоился о том, что nginx как-то блокирует соединение, поэтому я решил подключиться к Kestrel без какого-либо посредника. Я подключился к машине и выполнил следующую команду:

$ curl 127.0.0.1:5000/hubs/businesses?id=Tta4PmrjMrzHBHa8CT0SPQ -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> GET /hubs/myhub?id=Tta4PmrjMrzHBHa8CT0SPQ HTTP/1.1
> Host: 127.0.0.1:5000
> User-Agent: curl/7.52.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Date: Wed, 05 Jun 2019 06:26:09 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
<
* Curl_http_done: called premature == 0
* Connection #0 to host 127.0.0.1 left intact
No Connection with that ID

Итак, я получил ошибку 404 - как в браузере. Теперь я думаю, что никто не блокирует соединение как-то. Это просто что-то с конфигурацией SignalR не работает.

Почему SignalR может найти соединение?

Это имеет значение для какой машины я вошел в систему? соединение не передается через Redis как-то?

1 Ответ

0 голосов
/ 08 июня 2019

Когда у вас есть несколько экземпляров сервера за одним балансировщиком нагрузки, вам нужно включить липкие сеансы, что означает, что уникальный клиент будет когда-либо подключаться только к одному компьютеру.

Вы можете увидеть некоторую информацию о объединительной плате Redis в https://docs.microsoft.com/en-us/aspnet/core/signalr/scale?view=aspnetcore-2.2#redis-backplane

SignalR - это протокол, и часть этого протокола означает, что идентификатор соединения будет создан на сервере во время «согласования». Это означает, что вы не можете просто произвольно свернуть конечную точку с ID, потому что curl не понимает протокол SignalR.

Вы можете узнать больше о протоколе, если вы заинтересованы в https://github.com/aspnet/AspNetCore/tree/master/src/SignalR/docs/specs

...