Назад | Перейти на главную страницу

Рукопожатие socket.io не удается на балансировщике нагрузки https Google

У нас есть следующая настройка балансировщика нагрузки Google HTTPS.

Два внешних интерфейса: 1. HTTP-трафик на статический IP-адрес 2. HTTPS-трафик на тот же статический IP-адрес (DNS настроен на доменное имя)

Правила хоста и пути Все отправляются на бэкэнд

Один бэкэнд: с протоколом HTTP с привязкой сеанса к IP-адресу клиента

На внутреннем экземпляре есть приложение MEAN, работающее на порту 3000.

Из нашего клиентского приложения мы можем перейти к бэкэнд-приложению, используя доменное имя loadbalancer. Но у нас также есть функция чата с socket.io

Для подключения к сокету мы не смогли использовать доменное имя loadbalancer. Выдает ошибку 400.

Если мы попытаемся использовать внутренний IP-адрес напрямую для подключения к сокету, он будет работать, но если клиент находится на HTTPS, это создаст другую проблему, потому что серверная часть - это http.

В документации Google говорится, что loadbalancer по умолчанию поддерживает веб-сокеты. Так что не уверен, что происходит. Все остальные примеры, которые я вижу, относительно старые и, я думаю, не актуальны. Любая помощь приветствуется. Спасибо.

Для WebSockets через балансировщик нагрузки HTTP (S) тайм-аут серверной службы (ответа) является пределом времени жизни соединения (соединения WebSockets прерываются после настроенного тайм-аута ответа). Следовательно, таймаут должен быть установлен на максимальное время, в течение которого соединение WebSocket будет оставаться открытым. Соответствующее значение тайм-аута ответа зависит от используемого вами приложения.

Вам нужно будет провести несколько экспериментов, чтобы найти подходящий тайм-аут ответа, чтобы избежать закрытия тайм-аута соединения (немного увеличьте его значение и повторите попытку; например, если 30 секунд недостаточно, попробуйте 40 секунд, 50 секунд и т. Д.).

Найти на Переполнение стека.

Херро, я бился над отладкой этой проблемы в течение 2 недель.

Комментарий @ jfriend00 послужил провидением для моего плебейского ума.

В конечной точке развертывания nodejs я должен передать следующий порядок транспортов:

  app = express()
  server = require('http').Server(app)# {key: tlskey, cert: tlscert},app)
  io = require('socket.io')(server, { transports: ['websocket', 'polling'], cookie:true, secure: true })
  app.use bodyParser.urlencoded(extended: true)

Что происходит? Я указываю socket.io явно использовать транспорт websocket. Если это не удается, вернитесь к опросу. Поскольку HTTPS GCE Ingress устанавливает некоторые заголовки (выполняет некоторые обновления заголовков до wss), мне нужен secure:true flag, чтобы сопоставить их на моем сервере. Без вышеупомянутого error 400 происходит на стороне клиента.

Сервис работает как NodePort, с Generate_Cookie.

Если это все еще не удается, попробуйте просто transports: ['polling'], это самый простой протокол.

Вот ссылка на socket.io doc