У нас есть следующая настройка балансировщика нагрузки 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