@lexbond13
Web разработчик

Перестал работать Websocket после перехода на HTTPS. Чего менять?

Имеется сервис, написанный на Go. На нём поднят Http сервер на порту 8090, также там поднят сокет.
Имеется приложение на Php, которое слушает события по этому сокету. Всё это добро находится на одном сервере, приложение к сервису обращается через JS так:

conn = new WebSocket("ws://192.168.1.20:8090/events");


Всё работает, всё здорово. Наступает момент привязки к приложению PUSH-уведомлений, требующих HTTPS. Поднимаем Https, получаем пуши, но видим что сокет отвалился. В консоли ошибка:
Mixed Content: The page at 'https://mysite.ru/admin/service' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://192.168.1.20:8090/events'. This request has been blocked; this endpoint must be available over WSS.
Погуглив видим что сейчас нужно подключаться с префиксом WSS. Меняем префикс, получаем следующее:
WebSocket connection to 'wss://192.168.1.20:8090/events' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR

Что испробовано:

Читал что можно обойти проблему через nginx proxy, но как? Ловить коннект по порту 8090 и слать его на http, чтобы всё было как раньше? Пробовал, успеха особо не принесло.
Добавить поддержку https в сервис GO? Но какой сертификат? Тот же что и на само приложение?
  • Вопрос задан
  • 7039 просмотров
Решения вопроса 1
@lexbond13 Автор вопроса
Web разработчик
Спасибо за советы, решение было следующим:
1. В GO подключаем те же SSL сертификаты, что используются для Https для приложения
2. Проверяем что сервис доступен по домену https://mysite.ru:8090
3. Меняем адрес подключения к сокетам в приложении с ws://192.168.1.20:8090/events на wss://mysite.ru:8090/events , так как сертификат у нас для домена mysite.
4. Проверяем - всё работает!
Нюанс в том, что теперь передача данных происходит с очень большими задержками. Вероятно это из-за установки соединения по Https.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Robur
@Robur
Знаю больше чем это необходимо
А вы поддержку SSL для вебсокетов включили на сервере или только префикс в строке поменяли?
У вас по вопросу непонятно кто там слушает сокет - go или php. Я так понимаю что все таки go, wss настраивайте так же как и https, если https у вас работает без проблем, то с wss проблем быть не должно
Ответ написан
@redamo
Адрес с веба https://mysite.ru/ws

nginx
...
location /ws/ {
include proxy_params;
proxy_pass 127.0.0.1:8090/ws;
proxy_set_header Upgrade websocket;
proxy_set_header Connection Upgrade;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
}
....

в коде:
func wsEndpoint(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
upgrader.CheckOrigin = func(r *http.Request) bool { return true }

ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
}

log.Println("Client Connected")
err = ws.WriteMessage(1, []byte("Hi Client, URA!"))
if err != nil {
log.Println(err)
}
reader(ws)
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы