У меня есть рабочая установка socket.io с JavaScript -клиентом и python -сервером. Клиент в основном состоит из одной строки: Ошибка во время рукопожатия WebSocket: Неожиданный код ответа: 404
socket = io.connect('');
Сценарий сервера можно найти по адресу https://github.com/miguelgrinberg/python-socketio/blob/master/examples/server/wsgi/app.py - я запускаю сервер на порту 5000.
Все, что вам, вероятно, нужно знать о клиенте и сервере, - это то, что они отлично работают на моей установке localhost apache и что socket.io запускается с GET-запросов и обновлений до веб-сокета оттуда. Вот как выглядит успешное рукопожатие:
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=N1kLfSx
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=N1kLfTI&sid=70ddae8b36da4f0f8f9a851fa2c0121e
ws://localhost:5000/socket.io/?EIO=3&transport=websocket&sid=70ddae8b36da4f0f8f9a851fa2c0121e
Теперь у нас есть веб-розетка, и остальная часть связи проходит через это.
Я пытаюсь в течение двух дней: чтобы запустить пример на моем веб-сервере - поэтому я ищу рабочую конфигурацию apache https, которая передает запросы на мой сервер на порт 5000.
Я перепробовал десятки вариантов конфигураций, но ни одна из них работает - все они очень похожи на это. Часть, предназначенная для перезаписи URL, предназначена для прокси подключения к веб-сокету после успешного начального рукопожатия.
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:5000/$1 [P,L]
ProxyPass /socket.io/ http://localhost:5000/socket.io/
ProxyPassReverse /socket.io/ http://localhost:5000/socket.io/
Apache перенаправляет первый GET-запрос socket.io на сервер, а сервер отвечает:
ÿ0{"sid":"2efa0dbbce4c4eef958e70b393639610","upgrades":["websocket"],"pingTimeout":60000,"pingInterval":25000}ÿ42["my_response",{"data":"Connected","count":0}]ÿ40
Затем веб-розетка открывается и закрывается снова (код 404). Затем клиент отправляет запрос POST, который не выполняется (код 400). Затем клиент начинает сначала с шага 1: делает GET-запрос, получает новый идентификатор сеанса ...
(специальные символы ÿXX
также появляются в рабочем сообщении localhost - поэтому они, кажется, принадлежат там).
Что я делаю не так?
ОБНОВЛЕНИЕ - приближаемся к решению!
Я пробовал несколько Python и NodeJS реализаций примера сервера socket.io а также несколько клиентских скриптов - все они создали одну и ту же проблему, которая подтвердила мой тезис о том, что проблема Apache.
Я установил Nginx и нашел конфигурацию, которая наконец-то сработала! Это волшебные c строки:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Я сейчас использую отладочный сервер, который печатает все полученные HTTP-запросы, чтобы сравнить Nginx запросы с запросами Apache2 с целью настройки Apache2 передать те же заголовки, что и Nginx.
Последняя проблема, похоже, заключается в переводе строк конфигурации Nginx в Apache2. Звучит проще, чем это ... но это будет ключом к решению.