Socket.io: Ошибка во время рукопожатия WebSocket: Неожиданный код ответа: 400

Созданный на 14 янв. 2015  ·  129Комментарии  ·  Источник: socketio/socket.io

Не могу найти решение, я получаю эту ошибку в консоли браузера:
Сбой подключения WebSocket к «ws://.../socket.io/?EIO=2&transport=websocket&sid=p3af7ZNfvogtq6tAAAG0»: ошибка во время рукопожатия WebSocket: неожиданный код ответа: 400.

Хава любой совет?

Самый полезный комментарий

Была такая же проблема, мое приложение стоит за nginx. Внесение этих изменений в мою конфигурацию Nginx устранило ошибку.

место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}

Это исходно из https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/

Все 129 Комментарий

У меня точно такая же проблема в данный момент, любая помощь?

У меня также возникла эта проблема, так как я установил сертификат SSL в своем домене.

Вот лучшее описание проблемы: http://stackoverflow.com/questions/28025073/error-during-websocket-handshake-unexpected-response-code-400-with-nginx-proxy

У меня также есть аналогичная проблема с подключением к одной из библиотек Android. Веб-сокеты не будут подключаться к https ни через HAproxy, выполняющий завершение ssl, ни через то, чтобы узел выполнял ssl напрямую. Однако длинный опрос работает нормально

Я решаю это, изменив домен на истинный IP-адрес:

var socket = io.connect('http://182.92.79.215:3007');

Была такая же проблема, мое приложение стоит за nginx. Внесение этих изменений в мою конфигурацию Nginx устранило ошибку.

место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}

Это исходно из https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/

Та же проблема здесь, на рабочем сервере. Машины разработки не показывают ошибку.

Странно, что связь работает. Я могу отправлять сообщения через WebSockets с сервера, а клиент их получает. Я также вижу, как на сервере устанавливается соединение WebSocket.

Я просто получаю эту ошибку в инструментах разработчика, говоря:

Соединение WebSocket с ' wss://.../socket.io/?EIO=3&transport=websocket&sid=2b_v_BXtbwzl5z2yAAAI ' не удалось: ошибка во время рукопожатия WebSocket: Неожиданный код ответа: 400

Я использую Apache ProxyPass для отправки соединений на node.

То же самое здесь - полный функционал, но сообщение об ошибке в инструментах разработчика. Где-то еще я читал, что это связано с версией apache - с использованием 2.2.14 на этой машине.

Убедитесь, что ваше соединение socket.io не проходит через Amazon Load Balancer. Или, если да, сделайте это: http://blog.flux7.com/web-apps-websockets-with-aws-elastic-load-balancing

Та же проблема здесь, только в производственной среде.
Вебсокеты вроде работают корректно, приложение работает без проблем. Но в журнале консоли я вижу эту ошибку.

Я использую Nginx и только один сервер для узла, поэтому проблема с балансировкой нагрузки, похоже, не возникает. Я уже использовал решение, предложенное tylercb (за исключением «proxy_set_header Host $host;»), и оно не решает проблему.

тоже есть проблемы, но работают хорошо....

У меня была такая же проблема. Вы используете CloudFlare? В настоящее время только их план Enterprise поддерживает WebSockets.

Решено для меня. Это произошло из-за неправильного адреса socket.io в конфигурации nginx, который не соответствовал пути с использованием веб-сокета.

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

прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;

в файл конфигурации nginx, как упоминалось tylercb.

Работал на меня. Спасибо.

Получил ту же ошибку при прямом подключении к моему приложению, размещенному на Windows Server 2008R2 (без прокси, без IIS). Только тупое промежуточное оборудование между ними.

Работает нормально после переключения имени хоста на IP-адрес, т.е. 127.0.0.1:9000. может быть вызвано httpd ProxyPassReverse

В моем случае проблема возникла из-за того, что облачная служба не поддерживает веб-сокеты в бесплатном плане. Я отключил CloudFare для домена, и это сработало.

Мне просто нужно было добавить некоторые условия перезаписи Apache для обработки веб-сокетов, подробнее здесь:
http://stackoverflow.com/a/27534443/2044993

Я знаю, что это старая проблема, но, поскольку она высоко в результатах поиска Google, это может помочь людям:

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

Кстати, этот вопрос должен оставаться закрытым, это не проблема socket.io.

@arosenfeld-mentel Я продолжаю читать сообщения над вашим комментарием о том, что «это не проблема socket.io», но я не вижу, где кто-то говорит, В ЧЕМ на самом деле проблема. Я сам это вижу, хотя, как вы говорите, связь все еще работает. Любые советы будут очень благодарны. Спасибо!

На самом деле проблема может быть в чем угодно, вам нужно отладить всю настройку. Для меня это был NGINX, который в качестве обратного прокси нуждается в дополнительных настройках конфигурации, опубликованных выше много раз. Ведь ты можешь быть кем-то другим.

Начните с отладки локального соединения, заставьте его работать без предупреждения, затем перейдите на рабочий сервер и убедитесь, что у вас есть брандмауэры, внешние серверы и прокси для взаимодействия с WebSockets.

Это не проблема socket.io, а проблема WebSockets, поэтому убедитесь, что сервер и клиент хорошо работают с WebSockets.

Спасибо за ответ. Все работает локально или через наш VPN, но как только включается наш брандмауэр, появляются сообщения. Я предполагаю, что брандмауэр каким-то образом мешает, и нам придется научиться отлаживать эту проблему, а не обвинять socket.io. Еще раз спасибо.

Имея точно такую ​​же проблему. У меня также есть вопрос о создании stackoverflow (http://stackoverflow.com/questions/34439546/socket-io-with-apache-proxy), но предложенные там вещи еще не работали для меня.

я поместил эти заголовки в nginx, но все равно получаю то же самое, но не в браузере, а в https://toolbox.seositecheckup.com

У меня тоже была эта проблема, похоже, мой виртуальный хост (через nginx) не был правильно настроен для принятия заголовка Upgrade. Исправление @tylercb примерно год назад исправило это ^

@tylercb работал на меня.

+1
Эта ошибка возникла в среде openshift

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

Мы бежим

  1. Сервер Ubuntu 14.04 LTS,
  2. Версия nginx: nginx/1.4.6 (Ubuntu) в качестве обратного прокси-сервера и шлюза SSL.
  3. У нас вообще НЕТ Апача. Его удалили из системы.
  4. У нас есть сервер node.js, работающий за nginx v0.10.25. Это прослушивает порт 4001. Внешний доступ осуществляется через порт 4000.
  5. Мы запускаем ufw спереди и просто пропускаем порт 4000.
  6. Мы управляем собственными серверами и не используем Cloudflare или Openshift.
  7. Мы не используем балансировщик нагрузки (пока).

У нас были те же проблемы, что и у других людей из

WebSocket connection to 'ws://XXXXXXXXXX?EIO=2&transport=websocket&sid=p3af7ZNfvogtq6tAAAG0' failed: Error during WebSocket handshake: Unexpected response code: 400.

Мы обновили файл nginx в /etc/nginx/sites-enabled/default, чтобы он читался следующим образом: (обратите внимание, мы вытащили наши доменные имена)

server {
        listen 4000;
        server_name XXXX.YYYY.ZZZZ;

        root html;
        index index.html index.htm;

        ssl on;
        ssl_certificate /etc/ssl/certs/SSL.crt;
        ssl_certificate_key /etc/ssl/private/server.key;

        ssl_session_timeout 5m;

        # ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; # NOTE WE REMOVE SSLv3
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES1\
28-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECD\
HE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SH\
A256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SH\
A:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

        ssl_prefer_server_ciphers on;
        ssl_dhparam /etc/ssl/private/dhparams.pem;

        location / {
                 proxy_set_header        Host $host;
                 proxy_set_header        X-Real-IP $remote_addr;
                 proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                 proxy_set_header        X-Forwarded-Proto $scheme;

                 # Fix the “It appears that your reverse proxy set up is broken" error.
                 proxy_pass          http://127.0.0.1:4001;
                 proxy_read_timeout  90;

                 proxy_redirect      http://127.0.0.1:4001 https://XXXXX.YYYYY.ZZZZZ;

                 # These three lines added as per https://github.com/socketio/socket.io/issues/1942 to remove the error
                 # WebSocket connection to 'wss://XXXXX.YYYYY.ZZZZZ:4000/socket.io/?EIO=3&transport=websocket&sid=0hsRiXu0q9p6RHQ8AAAC' failed:\
 Error during WebSocket handshake: Unexpected response code: 400 in console.log

                 proxy_http_version 1.1;
                 proxy_set_header   Upgrade $http_upgrade;
                 proxy_set_header   Connection "upgrade";
        }
}

Нам нужно было только добавить в

  1. прокси_http_версия 1.1;
  2. proxy_set_header Обновить $http_upgrade;
    3.proxy_set_header Соединение "обновление";

как у нас уже было

  1. proxy_set_header Хост $host;
  2. прокси_пасс http://127.0.0.1 :4001;

Надеюсь, это поможет, это сработало для нас.

Спасибо за помощь,

Роб

У меня такая же проблема, когда я аутентифицируюсь с помощью CAS (не в классической форме), и я использую Apache с LetEncrypt SSL в качестве прокси-сервера. Нужно ли устанавливать определенную конфигурацию?

Попытка развернуть приложение Node.js на AWS Elastic BeanStalk.
Я добавил папку .ebextensions в корень сервера, а внутри добавил файл nginx.config , который выглядит так:

server:
  location /:
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;

Я все еще получаю ошибку 400, но, по крайней мере, все остальные сокеты работают.

Для справки: это единственное рабочее решение для конфигурации, которое я нашел для socket.io 1.x и Apache 2.4: https://github.com/meteor/meteor/issues/3339#issuecomment -165188938

ProxyPass / http://localhost:3999/
ProxyPassReverse / http://localhost:3999/

RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://localhost:3999%{REQUEST_URI} [P]

используя другой порт, это может сработать

@BlaM спасибо за рабочую конфигурацию!

Для тех, кто столкнулся с этой проблемой в AWS Elastic Beanstalk, мне помог этот файл .ebextension :

files:
    "/etc/nginx/conf.d/01_websockets.conf" :
        mode: "000644"
        owner: root
        group: root
        content : |
            upstream nodejs {
                server 127.0.0.1:8081;
                keepalive 256;
            }

            server {
                listen 8080;

                location / {
                    proxy_pass  http://nodejs;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection "upgrade";
                    proxy_http_version 1.1;
                    proxy_set_header        Host            $host;
                    proxy_set_header        X-Real-IP       $remote_addr;
                    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                }
            }

    "/opt/elasticbeanstalk/hooks/appdeploy/enact/41_remove_eb_nginx_confg.sh":
        mode: "000755"
        owner: root
        group: root
        content : |
            mv /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf.old

По инструкции в этой теме .

@BlaM - я использую сервер Apache и ELB с Elastic Bean
Куда я должен поместить код, который вы предоставили?
Спасибо!

Я понятия не имею об Elastic Bean, но фрагмент кода, который я опубликовал, входит в файлы хоста Apache.

@tylercb Спасибо! это сработало для меня~

Кто-нибудь, не использующий nginx, сталкивается с такой же проблемой?

Да, я сталкиваюсь с теми же проблемами, используя Elastic Beanstalk с одним сервером (узел и nginx) без Elastic Load Balancer.
Я не знаю, как перейти с http/https на ssl/tls

Та же проблема с HAProxy здесь

Работал на меня. Спасибо. И вы должны обратить внимание на порядок

proxy_set_header   Upgrade $http_upgrade;
proxy_set_header   Connection "upgrade";

да, это сделало это и для меня.

Я также сталкиваюсь с этой проблемой. Даже с ошибкой 400 связь через веб-сокет между клиентом и сервером в порядке. Это в нашей среде разработки.

Может ли кто-нибудь сказать мне, будет ли это проблемой в производственной среде.

К вашему сведению: подключение к бэкэнду Sails с использованием socket.io, размещенного на Heroku, с использованием надстройки postgres вызовет эту ошибку в вашем браузере, если ваш io.sails.url не является https. Очень специфический случай, но, надеюсь, это поможет любому, у кого есть такой же стек, найти это в Google.

Всем привет,

Я также сталкиваюсь с той же проблемой на моей локальной машине. Мы используем python-flask в качестве сервера и HTML/CSS/JS в качестве интерфейса.

Во внешнем интерфейсе для подключения к серверу Websocket мы использовали
var socket = io.connect('ws://url/namespace', { 'transports': ['websocket'] });

При запуске приложения выдает ошибку
WebSocket connection to 'ws://url/namespace/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 400

Сообщите нам, если вам нужна дополнительная информация.

Любая помощь приветствуется.
Спасибо, что прочитали это.

С Уважением
Аджай

У меня такая же ошибка в примере приложения webrtc. На стороне сервера код

var server = require('http').Server(app);
var io = require('socket.io')(сервер);
var WebRTC = требуется ('../../');
app.use(express.static(__dirname));
var io = require('socket.io')(сервер);

После комментирования второго "require('socket.io')" сообщение об ошибке 400 исчезает.

Нужно копать дальше, почему ... но вы можете проверить, пытается ли ваше приложение дважды установить одно и то же соединение.

Привет, ребята, я знаю, что это обсуждение продолжается уже некоторое время, и я хотел опубликовать ресурс, который решил эту проблему для меня, используя AWS EBS с Application Load Balancer.

https://mixmax.com/blog/deploying-meteor-to-elastic-beanstalk-1

Надеюсь, это поможет.

Трэвис

У меня такая же проблема, когда я использую etherpad-lite.
Я нашел способ исправить проблему Apache ProxyPass.
Я использую Apache http 2.2, использует backprot из модуля wstunnel http 2.4, поэтому я думаю, что это также может исправить v.2.4.

Сначала я изменил socket.io-client/socket.io.js
ищите WS.prototype.uri = function()
return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
затем измените на:

return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path +'ws/'+ query;
сохраните его и перезапустите node.

Во-вторых, измените vhost.conf или ssl.conf.
добавьте следующее в VirtualHost:

        ProxyPass "/etherpad/socket.io/ws/" "ws://localhost:9001/socket.io/"
        ProxyPassReverse "/etherpad/socket.io/ws/" "ws://localhost:9001/socket.io/"

        ProxyPass "/etherpad/socket.io/" "http://localhost:9001/socket.io/"
        ProxyPassReverse "/etherpad/socket.io/" "http://localhost:9001/socket.io/"


        ProxyPass /etherpad/ http://localhost:9001/
        ProxyPassReverse /etherpad/ http://localhost:9001/
        CacheDisable *

        ProxyPreserveHost on
        <Proxy *>
                Options FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Proxy>

`

Перезапустите apache httpd, наслаждайтесь~

Для Apache следуйте ответу @cpres , он работает. моя конф

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName reservation.tinker.press

    DocumentRoot /var/www/html/node-js-order-socket-demo
    <Directory />
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
    RewriteRule .* ws://127.0.0.1:3001%{REQUEST_URI} [P]

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyVia Full
    <Proxy *>
        Require all granted
    </Proxy>

    ProxyPass / "http://127.0.0.1:3001/"
    ProxyPassReverse / "http://127.0.0.1:3001/"

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

apache-websocket-use-mode-rewrite

Мне также пришлось настроить эластичный балансировщик нагрузки для использования TCP через порт 80 вместо HTTP через порт 80.

Можно ли использовать директиву ProxyPass с несколькими узлами? В итоге я использовал RewriteRule для https://github.com/socketio/socket.io/pull/2819 :

Header add Set-Cookie "SERVERID=sticky.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

<Proxy "balancer://nodes_polling">
    BalancerMember "http://server-john:3000"    route=john
    BalancerMember "http://server-paul:3000"    route=paul
    BalancerMember "http://server-george:3000"  route=george
    BalancerMember "http://server-ringo:3000"   route=ringo
    ProxySet stickysession=SERVERID
</Proxy>

<Proxy "balancer://nodes_ws">
    BalancerMember "ws://server-john:3000"    route=john
    BalancerMember "ws://server-paul:3000"    route=paul
    BalancerMember "ws://server-george:3000"  route=george
    BalancerMember "ws://server-ringo:3000"   route=ringo
    ProxySet stickysession=SERVERID
</Proxy>

RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) balancer://nodes_ws/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) balancer://nodes_polling/$1 [P,L]

@darrachequesne Это сработало просто отлично! Благодарность

Спасибо!

Для тех, у кого все еще есть проблема с AWS Application Load Balancer, попробуйте обновить свою политику безопасности, я столкнулся с той же проблемой, хотя она отлично работала в точной настройке для другого веб-сайта, но заметил, что политика безопасности отставала примерно на 1 год. Обновив его на более новый, похоже, проблема решилась.

Настроив nginx и клиент, я все еще пытался найти точное решение.
Но @visibleajay сделал этот комментарий, и я понял, что не использовал часть { 'transports': ['websocket']} в команде io.connect.

Так что для тех, кто может столкнуться с той же проблемой,
var socket = io.connect('https://server.com/socket.io-path-here', { 'transports': ['websocket'] });

сделал свою работу вместе с правильными конфигурациями nginx.

@ fott1 имейте в виду, что использование { 'transports': ['websocket'] } означает, что нет возможности вернуться к длительному опросу, когда соединение через веб-сокет не может быть установлено.

Полный пример с nginx: https://github.com/socketio/socket.io/tree/master/examples/cluster-nginx

@darrachequesne Я считаю, что вы правы, что, если я включу в массив вместе с «websocket» «опрос» или «xhr-опрос»? Спасибо за предоставленный пример.

@fott1 по умолчанию действительно ['polling', 'websocket'] ( ref ).

Но вам нужно будет использовать правильную конфигурацию nginx, поскольку транспорт polling (в отличие от websocket ) требует, чтобы каждый запрос направлялся на один и тот же сервер socket.io.

@darrachequesne другими словами. если у меня есть несколько экземпляров сервера, каждый запрос должен направляться в один и тот же экземпляр? Поправьте меня, если я ошибаюсь. Спасибо за совет.

@ fott1 да, верно. Объяснение здесь: https://socket.io/docs/using-multiple-nodes/

FWIW - я получал это на своем локальном компьютере (без nginx, без прокси). Оказывается, с socket.io вы должны явно указать транспорты как первый веб-сокет, а затем опрос - как на клиенте, так и на сервере. Не знаю, почему это не было бы просто по умолчанию. Или, может быть, я делаю это неправильно.

Наша первоначальная проблема заключалась в том, что у нас был опрос до веб-сокета, и мы не понимали, что порядок имеет значение.

Оригинальная установка:
сервер:
io.set('transports', ['polling', 'websocket']);
клиент:
var socket = io.connect(server, { reconnect: true });

Мы поняли, что наш клиент проводил опрос, поэтому убрали это как вариант. Затем все начало давать сбои, и мы получили 400 неверных запросов.

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

Исправить:
сервер:
io.set('transports', ['websocket', 'polling']);
клиент:
var socket = io.connect(server, { reconnect: true, transports: ['websocket', 'polling'] });

Опять же, имейте в виду, что использование { 'transports': ['websocket', 'polling'] } означает, что нет возможности вернуться к длительному опросу, когда соединение через веб-сокет не может быть установлено.

Давайте закроем эту тему, пожалуйста, откройте снова, если это необходимо.

Я выбрал подход «расширения» стандартной конфигурации nginx Elastic Beanstalk с настройками местоположения, аналогичными некоторым более ранним предложениям. Создайте структуру каталогов следующим образом:

 ~/рабочая область/мое-приложение/
 |-- .ebextensions
 | `-- нгинкс
 | `-- conf.d
 | `-- myconf.conf
 `-- web.jar

где myconf.conf , имя которого может быть произвольным, если оно заканчивается на .conf , содержит следующее:

 сервер {
 место расположения / {
 прокси_пароль http://127.0.0.1:5000;
 прокси_http_версия 1.1;
 proxy_set_header Обновить $http_upgrade;
 proxy_set_header Соединение "обновление";
 proxy_set_header Хост $host;
 }
 }

Не забудьте настроить номер порта в соответствии с вашими потребностями.

Я решил эту проблему, добавив только {transports: ['polling'] } .

_

var socket = io.connect(сервер, {транспорт: ['опрос']});

_

@ hyewon330 Судя по всему, вы на самом деле не _решили_ это 😉 Вы просто настроили socket.io, чтобы даже не пытаться использовать веб-сокеты. Конечно, сообщение об ошибке исчезло, но теперь вы заставляете socket.io использовать опрос, даже если соединение между клиентом и сервером _будет_ поддерживать веб-сокеты. Не уверен, что это критично для вашего приложения, просто хотел убедиться, что вы знаете 👌

Для тех, кто использует Nginx , решение @tylercb отлично работает.

Это решение решило мою проблему с блестящими приложениями. префект.

@tylercb @rudolfschmidt @juanjoLenero @rwillett @cpres привет, я использую ваш метод, но он у меня не работает. Сомневаюсь, потому что я использую другой порт, а не 8080. Например, мое приложение помещается на машину A с IP 170.8.8.8 для мониторинга порта 5000, а я помещаю nginx на машину B с IP 170.8.8.2 также для мониторинга порта 5000. Поэтому я хотите посетить IP: 5000 в B, который переходит к IP: 5000 в A. Ниже приведена моя конфигурация nginx на машине B:

upstream cuitccol.com{ #the name of server cluster
        server 170.8.8.8:5000 max_fails=5 fail_timeout=50s; #for the first web server
        }

    server {
        listen       5000;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass http://cuitccol.com;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
        } 

Я не знаю, где идет не так. Можете ли вы дать несколько советов?
большое спасибо~
Ждем Вашего ответа

Я уже некоторое время сталкиваюсь с этой проблемой в каждой среде, включая локальную. @darrachequesne Дайте мне знать, если мне нужно предоставить дополнительную информацию:

У меня есть узел js с экспрессом и приведенный ниже код, который точно соответствует разделу socket.io «Как использовать»:

var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(){ /* … */ });
server.listen(3000);

И я настроил очень простой клиент, используя только приведенный ниже код, который точно соответствует разделу socket.io-client «Как использовать»:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io('http://localhost:3000');
  socket.on('connect', function(){});
  socket.on('event', function(data){});
  socket.on('disconnect', function(){});
</script>

Несмотря на успешное подключение, я продолжаю получать ту же ошибку:

Соединение WebSocket с 'ws:// localhost:3000/socket.io/?EIO=3&transport=websocket&sid=EWl2jAgb5dOGXwScAAAB ' не удалось: ошибка во время рукопожатия WebSocket: Неожиданный код ответа: 400

При просмотре консоли браузера ошибка указывает на строку 112 из websocket.js, в которой говорится:

try {
    this.ws = this.usingBrowserWebSocket ? (protocols ? new WebSocket(uri, protocols) : new WebSocket(uri)) : new WebSocket(uri, protocols, opts);
  } catch (err) {
    return this.emit('error', err);
  }

Рад любым идеям...

@rafapetter Убедитесь, что вы не запрашивали socket.io дважды, я перемещал настройку socket.io в www/bin в app.js и случайно оставил в корзине требуемый socket.io, который вызывал эту ошибку.

Просто добавьте опцию {transports: ['websocket']} в клиент Socket.io.

выглядеть так.

import io from 'socket.io-client'
const socket = io('http://localhost:5000', {transports: ['websocket']})

@spookyUnknownUser на сервере socket.io требуется только один раз.

@prapansak клиент представляет собой простой файл javascript внутри функции window.onload , импорт ES6 не разрешен. Но я следую разделу «Как использовать»:
<script src="/socket.io/socket.io.js"></script>

И при вызове сокета, как вы предложили:
const socket = io('http://localhost:5000', {transports: ['websocket']})

Я получаю эту ошибку: соединение WebSocket с 'ws:// localhost:1337/socket.io/?EIO=3&transport=websocket ' не удалось: неверный заголовок кадра

Спасибо, ребята, если у вас есть другие идеи, дайте мне знать, и я попробую это здесь.

Хорошо, наконец-то разобрались!

@spookyUnknownUser, ваша идея побуждает меня искать дубликаты дальше. И как оказалось, на сервере сразу после server.listen я делал так:

io.attach(server, {
  pingInterval: 40000,
  pingTimeout: 25000,
});

В каком-то смысле я думаю, что сервер подключается во второй раз. Поэтому я удалил его и в самом начале, когда требовался socket.io, я изменил его на:

var io = require('socket.io')(server, {
    'pingInterval': 40000,
    'pingTimeout': 25000
});

Теперь никаких проблем не наблюдается, все работает нормально.

Еще раз спасибо за инфу, ребята

У меня есть сервер сокетов на EBS (AWS Elastic beanstalk). Я столкнулся с аналогичной проблемой в производственной среде, но смог решить ее без перехода на балансировщик нагрузки приложений и без изменения конфигураций ngnix или apache.

Изменения, которые я внес для решения этой проблемы: вместо https я разрешил ssl на 443 порту моего приложения и открыл порт 443 в своей группе безопасности.

ebs_lb
ebs_sg

Для пользователей AWS: используйте Application Load Balancer и убедитесь, что в целевой группе включена функция закрепления.

Оказывается, это периодически происходило на нашем сервере, когда он был перегружен и в период пиковой нагрузки.

Разрешение настроек по умолчанию при срабатывании io.connect создает запросы XHR и запрос WS вскоре после этого (как упоминалось выше). Все эти запросы XHR перегружали сервер и, таким образом, возвращали 400 ошибок. Используя приведенные выше предложения по добавлению transports: ['websocket']} в клиентский код, проблема была решена. Будет опубликовано обновление, если 400 ошибок не исчезнут, но пока это кажется надежным.

есть та же проблема, ни одно из предложенных выше изменений на стороне сервера не решило ее. На стороне клиента у меня есть socket = io.connect(); в модуле реагирования, и он может определить, к какому серверу я подключаюсь.
Предоставление параметра server для подключения довольно хлопотно, но без него как я могу указать { reconnect: true, transports: ['websocket', 'polling'] } ? Похоже, необязательный параметр № 1, но решающий параметр № 2

я добавил это ниже, и это сработало для меня.
место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}
https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/

К сожалению, у меня такая же проблема, даже с хорошим набором заголовков. Я создал stackoverflow с моей конфигурацией.

https://stackoverflow.com/questions/50431587/proxy-socket-io-fails-to-connect-with-nginx-node-on-docker

Обратите внимание на двойные кавычки здесь:

proxy_set_header Соединение "обновление";

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

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

см. здесь

Решение tylercb сработало для меня (NgInx). Спасибо!

Ключом для нас был proxy_http_version 1.1; в решении @tylercb .

Я отредактировал конфигурацию NginX на своем сервере в соответствии с этими многочисленными комментариями.
Но работает частично. Сначала, после перезагрузки сервера, он работает плохо. В основном с жестким обновлением. Позже это работает лучше, просто иногда требуется жесткое обновление.
Локально с sails lift работает
Но если я использую локально sails lift --prod , то я получаю то же самое, этот сокет не может подключиться и 400 плохой ответ. Но после некоторых попыток снова стабильно.

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

Я добавил различные конфигурации в документацию: https://socket.io/docs/using-multiple-nodes/

Приветствуются любые предложения по улучшению! => https://github.com/socketio/socket.io-веб-сайт

Я просто сталкиваюсь с этой проблемой и все еще получаю сообщение об ошибке, даже отключая мой nginx. Наконец, проблема из-за промежуточного программного обеспечения express-status-monitor в экспрессе делает HTTP-вызов при первом (запросном) рукопожатии WebSocket неудачным.

Я пытаюсь отключить это промежуточное ПО, и WebSocket работает хорошо.

Есть несколько причин, по которым вы получите 400 во время рукопожатия. Ниже приведены несколько вещей, которые можно попробовать

  1. Включите 443 в (ufw/Другое) брандмауэрах, а также в настройках (AWS/Google cloud/Другое) консоли
  2. Не включайте TLS на сервере nodejs. Делайте это через nginx.
  3. Используйте следующую конфигурацию nginx
    Примечание. Это работает только в том случае, если ваше соединение socket.io уже работает, но использует длинный опрос вместо веб-сокетов. Добавьте приведенный ниже код, и он начнет использовать веб-сокет.
        location /{
            proxy_pass http://127.0.0.1:5000/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
        }

Может быть, это будет помощь для кого-то. Я получил эту ошибку, когда создал два экземпляра socket.io в своем приложении. Я назвал io = socketio(server) twise и получил ошибку 400. Это какие-то глупые ошибки, но... это было мое.

Убедитесь, что вы включили сеансы Sticky в балансировщике нагрузки вашего приложения (не используйте классический балансировщик нагрузки). Если вы не используете фиксированные сеансы, вы, вероятно, получите 400 ошибок случайным образом.

Это связано с тем, что при попытке перехода с опроса на веб-сокет балансировщик нагрузки балансирует запрос на обновление с сервером, который никогда не сталкивался с этим идентификатором сокета, и выдает ошибку 400. Подробнее здесь: https://socket.io/docs/using-multiple-nodes/

Кроме того, если вы используете эластичный beanstalk, добавьте следующий файл websocket.config в папку .ebextensions для поддержки обновления Nginx до Websockets:

container_commands:
  enable_websockets:
    command: |
     sed -i '/\s*proxy_set_header\s*Connection/c \
              proxy_set_header Upgrade $http_upgrade;\
              proxy_set_header Connection "upgrade";\
      ' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

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

прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;

в файл конфигурации nginx, как упоминалось tylercb.

Так что, по крайней мере, это работает, когда вы используете nginx в качестве обратного прокси, вот объяснение

WebSocket proxying
To turn a connection between a client and server from HTTP/1.1 into WebSocket, the protocol switch mechanism available in HTTP/1.1 is used.

There is one subtlety however: since the “Upgrade” is a hop-by-hop header, it is not passed from a client to proxied server. With forward proxying, clients may use the CONNECT method to circumvent this issue. This does not work with reverse proxying however, since clients are not aware of any proxy servers, and special processing on a proxy server is required.

Since version 1.3.13, nginx implements special mode of operation that allows setting up a tunnel between a client and proxied server if the proxied server returned a response with the code 101 (Switching Protocols), and the client asked for a protocol switch via the “Upgrade” header in a request.

As noted above, hop-by-hop headers including “Upgrade” and “Connection” are not passed from a client to proxied server, therefore in order for the proxied server to know about the client’s intention to switch a protocol to WebSocket, these headers have to be passed explicitly:

location /chat/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}
A more sophisticated example in which a value of the “Connection” header field in a request to the proxied server depends on the presence of the “Upgrade” field in the client request header:

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

    server {
        ...

        location /chat/ {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    }
By default, the connection will be closed if the proxied server does not transmit any data within 60 seconds. This timeout can be increased with the proxy_read_timeout directive. Alternatively, the proxied server can be configured to periodically send WebSocket ping frames to reset the timeout and check if the connection is still alive.

Есть новости по этому вопросу? Я сослался на это здесь https://stackoverflow.com/questions/49575350/websocket-connection-to-wss-error-during-websocket-handshake-unexpected-re

У многих пользователей эта проблема возникает из-за конфигурации nginx, и хотя на выделенных серверах вы можете исправить ее, используя приведенные выше идеи (конфигурация nginx и т. д.), у многих пользователей нет доступа к этим настройкам, поэтому было бы здорово иметь какой-то исправить с sockets.io на это...

Никто?

@deemeetree
Если вы используете несколько узлов, что мне кажется возможным из-за сообщения об ошибке на вашем сайте «Идентификатор сеанса неизвестен», вам следует взглянуть на мой ответ на StackOverflow (https://stackoverflow.com/a/53163917/6271092) .

Если быть кратким, socket.io как говорится на их сайте (https://socket.io/docs/using-multiple-nodes/) ,

Если вы планируете распределить нагрузку соединений между различными процессами или машинами, вы должны убедиться, что запросы, связанные с определенным идентификатором сеанса, соединяются с процессом, который их породил.

Это связано с тем, что некоторые транспорты, такие как опрос XHR или опрос JSONP, полагаются на запуск нескольких запросов в течение срока службы «сокета». Неспособность включить липкую балансировку приведет к ужасному:

Error during WebSocket handshake: Unexpected response code: 400

Таким образом, у вас не может быть нескольких сокетов, работающих на разных узлах. Перенастройте свой сервер, как он говорит. И для вашего Express настройте свой порт следующим образом,
parseInt(your_port) + parseInt(process.env.NODE_APP_INSTANCE);

Надеюсь, поможет.

Получил ту же ошибку при прямом подключении к моему приложению, размещенному на Windows Server 2008R2 (без прокси, без IIS). Только тупое промежуточное оборудование между ними.

Я столкнулся с той же проблемой на сервере Windows 2016, пожалуйста, укажите ваше исправление. Спасибо

Я столкнулся с этой проблемой в течение достаточно долгого времени. Если у кого-то есть какая-либо информация, пожалуйста, помогите. Я использую сервер Apache.

Любая подсказка? Отлично работает на dev, но та же проблема с SSL.

Использование режима кластера узлов PM2: 4 x 1

Использование прокси-сервера Apache, до сих пор не знаю

Для тех, кто находится на httpd2/apache2, у меня есть решение, которое работает:

    ProxyRequests Off
    <Location />
        ProxyPass http://127.0.0.1:1337/
        ProxyPassReverse http://127.0.0.1:1337/

        RewriteEngine On
        RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
        RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
        RewriteRule /socket.io/(.*) ws://127.0.0.1:1337/socket.io/$1 [P]
    </Location>

Эй, @ZeldaZach , это для файла .htaccess? Благодарность!

Эта конфигурация находится в моем файле sites-enabled/site.conf, но она должна работать и в htaccess.

Все, что я могу сказать, здесь виноват SSL :) отключите гибкий режим SSL в Cloudflare и перейдите в режим FULL (STRICT). Конечно, это решит проблему,
Если не,

Используйте localhost:port в конфигурации обратного прокси.

Для всех, кто использует Nginx и React Express (MERN). У меня была такая же проблема, потому что у меня была только строка proxy_pass http://localhost:3000; . Я добавил следующие строки на основе ответа @tylercb выше в этой теме:

«Была та же проблема, мое приложение находится за nginx. Внесение этих изменений в мою конфигурацию Nginx устранило ошибку.

location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}

Это исходно из https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/ "

Если у кого-то все еще есть проблемы с использованием Nodejs + Express, возможно, ваша проблема может быть express-status-monitor , как упоминал @slaveofcode . Как указано в его документации NPM , этот модуль порождает свой собственный экземпляр socket.io, поэтому вы должны заполнить параметр websocket вашим основным экземпляром socket.io, а также параметром порта:

const io = require('socket.io')(server);
const expressStatusMonitor = require('express-status-monitor');
app.use(expressStatusMonitor({
  websocket: io,
  port: app.get('port')
}));

Это моя конфигурация Apache, обратите внимание, что она использует префикс пути /ws/ , но в остальном она работает нормально.

    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    RewriteEngine On
    RewriteCond %{REQUEST_URI}  ^/ws/socket.io         [NC]
    RewriteCond %{QUERY_STRING} transport=websocket    [NC]
    RewriteRule /ws/(.*)           ws://localhost:6001/$1 [P,L]
    ProxyPass /ws http://127.0.0.1:6001
    ProxyPassReverse /ws http://127.0.0.1:6001

В настоящее время мы сталкиваемся с этой проблемой, связанной с предоставлением панели инструментов Linkerd (сервисной сетки) для нашего кластера EKS. мы используем nginx, поэтому не совсем уверены, как выйти из него в данный момент.

@andrzj ОМГ, чувак, ты только что спас меня.

Была такая же проблема, мое приложение стоит за nginx. Внесение этих изменений в мою конфигурацию Nginx устранило ошибку.

место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}

Это исходно из https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/

оно работает.

Спасибо за помощь банде! Если кто-то пытается заставить это работать рядом с обычным HTTPS-трафиком, теперь он работает на Elastic Beanstalk для меня со следующими настройками:

  • На Elastic Beanstalk: nginx отключен (пока еще не удосужился попробовать приведенную выше конфигурацию).
  • В Elastic Beanstalk: Балансировщик нагрузки выглядит следующим образом:
  • На узле/экспрессе: const io = require('socket.io')(3030)
  • На клиенте просто назовите let connection = io(https://www.myurl.com:3030)

Если у вас, ребята, все еще есть эта проблема, и вы установили разрешенный источник на сервере сокетов как массив или источники вместо функции обратного вызова для фильтрации источников, это вызовет эту ошибку.

Error during WebSocket handshake: Unexpected response code: 400

В моем случае обновление этой логики

io.origins(['https://foo.example.com:443']);

к этому

io.origins((origin, callback) => {  
     if (origin !== 'https://foo.example.com') {    
         return callback('origin not allowed', false);  
     }  
    callback(null, true);
});

Работал без каких-либо ошибок.

Получаю ту же ошибку, но я добавил в конфиги для NGINX, и я все еще получаю ту же ошибку рукопожатия 400. Однако я использую Application Load Balancer в AWS, и я установил для него целевую группу :80 и прослушиватель 443, который перенаправляется в целевую группу.

Файл конфигурации NGINX:

`сервер {

listen [::]:80;
listen 80;

server_name <domain_name>;
access_log  /var/log/nginx/access.log;

location / {
    proxy_pass http://127.0.0.1:8000;
    include proxy_params;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

location /socket.io {
    include proxy_params;
    proxy_http_version 1.1;
    proxy_cache_bypass $http_upgrade;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://127.0.0.1:8000;
}

}`

И в моем файле js у меня есть соединение для socket.io, которое выглядит так:
var socket = io()

Создайте экземпляр вручную (без экспресс-экземпляра app ) и назначьте другой порт

const io = require('socket.io')(3001, {
  path: '/',
  serveClient: false,
  // below are engine.IO options
  pingInterval: 10000,
  pingTimeout: 5000,
  cookie: false
})

Была такая же проблема, мое приложение стоит за nginx. Внесение этих изменений в мою конфигурацию Nginx устранило ошибку.

место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}

Это исходно из https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/

Мне не хватало proxy_set_header Connection "upgrade";

Я потратил целую ночь, чтобы решить эту проблему, когда начал использовать https или wss или ssl . Он всегда говорит connection stopped before establish с кодом ошибки 400 .

Буквально несколько минут назад я нашел решение для этого:

0. Облачная вспышка

На вкладке SSL/TLS:

  • Если у вас есть собственный cert или SSL или HTTPS : установите его на Full . (Следующие 123 шага предполагают, что у вас есть собственная сертификация https)

  • Если у вас есть только http server : установите его на Flexible . (Cloudflare автоматически добавит https или ssl на ваш сайт.)

  • После этого перейдите на вкладку DNS, установите Proxied .

Если вы не уверены, что делаете, просто перейдите на вкладку DNS, установите DNS only

1. Убедитесь, что у вас правильная конфигурация прокси.

server {
    listen 80;
    server_name ai-tools-online.xyz;
    return 301 https://ai-tools-online.xyz$request_uri;
}

server {
    listen 443 ssl http2;

    ssl_certificate       /data/v2ray.crt;
    ssl_certificate_key   /data/v2ray.key;
    ssl_protocols         TLSv1.2 TLSv1.3;
    #ssl_ciphers           3DES:RSA+3DES:!MD5;
    server_name ai-tools-online.xyz;

    location / {
        proxy_pass http://127.0.0.1:5000;
    }

    location /socket.io {
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:5000/socket.io;
    }
}

ai-tools-online.xyz — ваш домен, http://127.0.0.1:5000 — ваш сокет-сервер.

2. Убедитесь, что ваш сервер Cross-Origin Controls настроен на '*' , чтобы разрешить Cross-Origin Access

Для flask-socketio нужно использовать flask_socketio.SocketIO(app, cors_allowed_origins = '*')

3. Вы должны перезапустить nginx, чтобы новая конфигурация заработала.

systemctl restart nginx

4. Дополнительные сведения о том, как установить caddy , см. по следующим ссылкам:

https://github.com/yingshaoxo/Web-Math-Chat#reverse-proxy-configuration-for-https
https://caddy.community/t/using-caddy-0-9-1-with-socket-io-and-flask-socket-io/508/6
https://www.nginx.com/blog/nginx-nodejs-websockets-socketio/

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

прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;

в файл конфигурации nginx, как упоминалось tylercb.

сработало для меня хорошо, спасибо!

Если вы используете Elastic Beanstalk, как и я, для создания узла-сервера,
При создании среды нас спрашивают в конфигурациях, какой прокси-сервер использовать. В котором nginx предварительно заполнен или установлен по умолчанию.
Я установил для этого прокси-сервера значение none, а затем продолжил создание своего сервера. Я использовал Elastic Beanstalk для создания сервера узлов, в котором мой прокси-сервер по умолчанию был настроен на nginx.
Так как это ошибка настройки прокси-сервера. После удаления любого прокси-сервера ошибка пропадала.

Мы искали Google в течение нескольких часов, и ни одно из приведенных выше решений не применимо к нам, поскольку у нас было только приложение nodejs и не было nginx.

Мы решили эту проблему, просто отключив nginx из контейнера -> настройки балансировщика нагрузки, чтобы передать весь трафик непосредственно на узел.

Мы искали Google в течение нескольких часов, и ни одно из приведенных выше решений не применимо к нам, поскольку у нас было только приложение nodejs и не было nginx.

Мы решили эту проблему, просто отключив nginx из контейнера -> настройки балансировщика нагрузки, чтобы передать весь трафик непосредственно на узел.

Как ты это делаешь?

Если вы перейдете в «Конфигурация»> «Балансировщик нагрузки», вы можете найти раскрывающийся список для прокси-сервера, вы можете использовать nginx, Apache или установить для него значение «нет», чтобы проходить через все подключения к приложению узла.

Это появляется только в том случае, если вы создаете среду с балансировщиком нагрузки, не работает для отдельных экземпляров.

Изменить: мой первоначальный комментарий относился к Elastic Beanstalk

Была такая же проблема, мое приложение стоит за nginx. Внесение этих изменений в мою конфигурацию Nginx устранило ошибку.

место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}

Это исходно из https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/

Так что спасибооуу.

Этот документ предназначен для тех, кто использует laravel-echo-server, Nginx, socket.io и Redis-сервер с отдельным сервером между клиентским проектом и Redis-сервером.

Пожалуйста, перейдите по ссылке здесь .

Спасибо

У меня была эта проблема. Обновление моей конфигурации nginx не помогло, но решение @santhosh77h исправило это для меня. По какой-то причине передача массива разрешенных источников не работает, но использование обратного вызова работает.

Я использую веб-сокеты Nest.js (просто обертка вокруг Socket.io) и добавил в свой шлюз следующее:

afterInit(server: Server): any {
    const origins = getOrigins(); // returns an array of origin strings
    server.origins((origin, cb) => {
      if (origins.includes(origin)) {
        cb(null, true)
      } else {
        cb('Invalid origin', false);
      }
    });
  }

У меня была такая же проблема с NUXT.js с Node.js/Express , работающим на AWS Elastic Beanstalk (прокси-сервер Nginx) . Мне понадобилось несколько дней, чтобы понять это. Я поделюсь своими точками чтения. Может быть, кто-то найдет это полезным.

Моя среда находится в Application Load Balancer с двумя портами 80 для https и 443 для https с SSL.

В сочетании с ответом выше, большое спасибо @tylercb и официальной документации от AWS и документации socket.io, я создал файл конфигурации Nginx, который, похоже, решает проблему.

Я быстро обрисую шаги:

В моем файле узла index.js:

const express = require('express')
const app = express()
const server = http.createServer(app)
const io = require('socket.io')(server)
const host = process.env.HOST || '127.0.0.1'
const port = process.env.PORT || 8081

На интерфейсе (один из моих компонентов):
import io from 'socket.io-client';
в моих данных Vue():
socket: io()

Наконец, в корне приложения я создал папку .ebextensions
Прямо внутри я создал файл 01-proxy.config следующего содержания:

files:
  /etc/nginx/conf.d/01-proxy.conf:
     mode: "000644"
     owner: root
     group: root
     content: |
        upstream nodejs {
          server 127.0.0.1:8081;
          keepalive 256;
        }
        server {
          listen 8080;
          server_name yourdomain.com;

          if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
            set $hour $4;
          }
          access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
          access_log  /var/log/nginx/access.log  main;

          location / {
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header Host $host;

              proxy_pass http://nodejs;

              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
          }

          gzip on;
          gzip_comp_level 4;
          gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

          location /static {
              alias /var/app/current/static;
          }

        }

  /opt/elasticbeanstalk/hooks/configdeploy/post/99_kill_default_nginx.sh:
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash -xe
      rm -f /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
      service nginx stop 
      service nginx start

container_commands:
  removeconfig:
    command: "rm -f /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf"

Дополнительные показания:
конфигурация nginx

Вот и все. Довольно продолжительный. Мои извинения и удачи.

работает для меня ниже изменений в сервере ubuntu и ngnix для ядра angular .net

место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}

Если у кого-то все еще есть проблемы с использованием Nodejs + Express, возможно, ваша проблема может быть express-status-monitor , как упоминал @slaveofcode . Как указано в его документации NPM , этот модуль порождает свой собственный экземпляр socket.io, поэтому вы должны заполнить параметр websocket вашим основным экземпляром socket.io, а также параметром порта:

const io = require('socket.io')(server);
const expressStatusMonitor = require('express-status-monitor');
app.use(expressStatusMonitor({
  websocket: io,
  port: app.get('port')
}));

Мне помогла эта информация

Убедитесь, что ваше соединение socket.io не проходит через Amazon Load Balancer. Или, если да, сделайте это: http://blog.flux7.com/web-apps-websockets-with-aws-elastic-load-balancing

Если у кого-то еще была эта проблема с использованием балансировщика нагрузки AWS, в упомянутой статье не говорится, что также возможно использовать SSL в качестве протокола балансировщика нагрузки и продолжать использовать свой сертификат в этой конфигурации, вне уровня вашего сервера приложений.

Так выглядят мои слушатели LB

image

Работал хорошо для меня!

Была такая же проблема, мое приложение стоит за nginx. Внесение этих изменений в мою конфигурацию Nginx устранило ошибку.

место расположения / {
proxy_pass http://localhost :8080;
прокси_http_версия 1.1;
proxy_set_header Обновить $http_upgrade;
proxy_set_header Соединение "обновление";
proxy_set_header Хост $host;
}

Это исходно из https://chrislea.com/2013/02/23/proxying-websockets-with-nginx/

да. Это было полезно и сработало и для меня.

Убедитесь, что ваше соединение socket.io не проходит через Amazon Load Balancer. Или, если да, сделайте это: http://blog.flux7.com/web-apps-websockets-with-aws-elastic-load-balancing

Если у кого-то еще была эта проблема с использованием балансировщика нагрузки AWS, в упомянутой статье не говорится, что также возможно использовать SSL в качестве протокола балансировщика нагрузки и продолжать использовать свой сертификат в этой конфигурации, вне уровня вашего сервера приложений.

Так выглядят мои слушатели LB

image

Работал хорошо для меня!

Красиво, сработало.

Убедитесь, что ваше соединение socket.io не проходит через Amazon Load Balancer. Или, если да, сделайте это: http://blog.flux7.com/web-apps-websockets-with-aws-elastic-load-balancing

Если у кого-то еще была эта проблема с использованием балансировщика нагрузки AWS, в упомянутой статье не говорится, что также возможно использовать SSL в качестве протокола балансировщика нагрузки и продолжать использовать свой сертификат в этой конфигурации, вне уровня вашего сервера приложений.

Так выглядят мои слушатели LB

image

Работал хорошо для меня!

в этом случае ваше приложение работает на 80?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги