Socket.io: WebSocket 핸드셰이크 중 오류: 예기치 않은 응답 코드: 400

에 만든 2015년 01월 14일  ·  129코멘트  ·  출처: socketio/socket.io

솔루션을 찾을 수 없습니다. 브라우저 콘솔에 다음 오류가 표시됩니다.
'ws://.../socket.io/?EIO=2&transport=websocket&sid=p3af7ZNfvogtq6tAAAG0'에 대한 WebSocket 연결 실패: WebSocket 핸드셰이크 중 오류: 예기치 않은 응답 코드: 400.

어떤 조언을 하바?

가장 유용한 댓글

같은 문제가 있었지만 내 앱은 nginx 뒤에 있습니다. 내 Nginx 구성을 변경하면 오류가 제거되었습니다.

위치 / {
proxy_pass http://localhost :8080;
proxy_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 라이브러리 중 하나와 연결하는 데 비슷한 문제가 있습니다. 웹 소켓은 HAproxy가 ssl 종료를 수행하거나 노드가 ssl을 직접 수행하도록 하여 https에 연결하지 않습니다. 긴 폴링은 잘 작동하지만

도메인을 실제 IP 주소로 변경하여 해결합니다.

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

같은 문제가 있었지만 내 앱은 nginx 뒤에 있습니다. 내 Nginx 구성을 변경하면 오류가 제거되었습니다.

위치 / {
proxy_pass http://localhost :8080;
proxy_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/ 에서 가져온 것입니다.

프로덕션 서버에서도 동일한 문제가 발생합니다. 개발 머신에는 오류가 표시되지 않습니다.

이상한 점은 연결이 작동하고 있다는 것입니다. 나는 서버에서 WebSocket을 통해 메시지를 보낼 수 있고 클라이언트는 메시지를 받습니다. 또한 서버에서 WebSocket 연결이 설정되는 것을 볼 수 있습니다.

개발자 도구에서 다음과 같은 오류가 발생합니다.

' wss://.../socket.io/?EIO=3&transport=websocket&sid=2b_v_BXtbwzl5z2yAAAI '에 대한 WebSocket 연결 실패: WebSocket 핸드셰이크 중 오류: 예기치 않은 응답 코드: 400

Apache ProxyPass를 사용하여 노드에 연결을 보내고 있습니다.

여기도 마찬가지입니다. 전체 기능이지만 개발 도구의 오류 메시지입니다. 다른 곳에서 이 머신에서 2.2.14를 사용하여 아파치 버전과 관련된 것을 읽었습니다.

socket.io 연결이 Amazon Load Balancer를 거치지 않는지 확인하십시오. 또는 그렇다면 다음을 수행하십시오. http://blog.flux7.com/web-apps-websockets-with-aws-elastic-load-balancing

프로덕션 환경에서만 동일한 문제가 발생합니다.
Websockets가 올바르게 작동하는 것 같으며 응용 프로그램이 문제 없이 작동합니다. 그러나 콘솔 로그에서 이 오류를 볼 수 있습니다.

Nginx를 사용하고 있고 노드에 하나의 서버만 사용하고 있으므로 로드 밸런싱 문제는 아닌 것 같습니다. 나는 이미 tylercb에서 제안한 솔루션("proxy_set_header Host $host;" 제외)을 사용하고 있었고 문제가 해결되지 않았습니다.

또한 문제가 있지만 잘 작동합니다....

나는이 같은 문제가 있었다. CloudFlare를 사용하고 있습니까? 현재는 엔터프라이즈 플랜 만 WebSocket을 지원합니다.

나를 위해 해결되었습니다. websocket을 사용하는 경로와 일치하지 않는 nginx 구성의 잘못된 socket.io 주소 때문이었습니다.

나는 같은 문제가 있었고 nginx도 사용하기 때문에 구글링했습니다. 해결책은 이 부분을 추가하는 것입니다

proxy_http_버전 1.1;
proxy_set_header 업그레이드 $http_upgrade;
proxy_set_header 연결 "업그레이드";
proxy_set_header 호스트 $host;

언급한 tylercb와 같은 nginx 구성 파일에 추가합니다.

나를 위해 일했다. 감사 해요.

Windows Server 2008R2(프록시 없음, IIS 없음)에서 호스팅되는 내 앱에 직접 연결하는 것과 동일한 오류가 발생했습니다. 그 사이에는 멍청한 중간 하드웨어만 있을 뿐입니다.

호스트 이름을 ip 주소(예: 127.0.0.1:9000)로 전환한 후 제대로 작동합니다. httpd ProxyPassReverse로 인해 발생할 수 있음

제 경우 문제는 무료 요금제에서 웹 소켓을 지원하지 않는 cloudfare의 결과였습니다. 도메인에 대해 CloudFare를 껐다가 작동했습니다.

웹 소켓을 처리하기 위해 Apache 재작성 조건을 추가해야 했습니다. 자세한 정보는 다음과 같습니다.
http://stackoverflow.com/a/27534443/2044993

나는 이것이 오래된 문제라는 것을 알고 있지만 Google 검색 결과에서 높기 때문에 사람들에게 도움이 될 수 있습니다.

이 오류가 발생해도 연결이 계속 작동하는 이유는 socket.io가 AJAX로 대체되기 때문입니다. 이는 최적이 아니므로 서버 구성을 수정해야 합니다.

Btw, 이 문제는 닫힌 상태로 유지되어야 하며 socket.io 문제가 아닙니다.

@arosenfeld-mentel "이것은 socket.io 문제가 아닙니다"라는 귀하의 댓글 위의 게시물을 계속 읽고 있지만 실제로 문제가 무엇인지 말하는 사람이 어디 있는지 모르겠습니다. 나는 당신이 말했듯이 연결이 여전히 작동하는 것처럼 보이지만 이것을 직접 봅니다. 모든 팁은 매우 감사하게 받을 것입니다. 감사 해요!

문제는 무엇이든 될 수 있습니다. 전체 설정을 디버그해야 합니다. 저에게 그것은 NGINX였습니다. 역 프록시는 위에 여러 번 게시된 추가 구성 설정을 필요로 합니다. 당신은 다른 사람이 될 수 있습니다.

로컬 연결을 디버깅하여 시작하고 경고 없이 작동하도록 한 다음 프로덕션 서버로 이동하여 WebSocket과 협력할 방화벽, 전면 서버 및 프록시를 확보하세요.

socket.io 문제가 아니라 WebSocket 문제이므로 서버와 클라이언트가 WebSocket과 잘 작동하는지 확인하십시오.

답장을 보내 주셔서 감사합니다. 모든 것이 로컬에서 또는 VPN을 통해 작동하지만 방화벽이 연결되면 메시지가 나타납니다. 방화벽이 어떻게든 간섭하고 있는 것 같으며 socket.io를 비난하는 대신 해당 문제를 디버그하는 방법을 배워야 할 것입니다. 다시 한번 감사합니다.

똑같은 문제가 있습니다. 나는 또한 stackoverflow (http://stackoverflow.com/questions/34439546/socket-io-with-apache-proxy) 질문을 만들었지 만 거기에서 제안한 것들이 아직 나를 위해 일하지 않았습니다.

이 헤더를 nginx에 넣었지만 여전히 동일하지만 브라우저가 아니라 https://toolbox.seositecheckup.com 에 있습니다.

이 문제도 발생하면 내 가상 호스트(nginx를 통해)가 업그레이드 헤더를 수락하도록 제대로 설정되지 않은 것 같습니다. @tylercb 님 의 약 1년 전 수정 사항이 수정되었습니다^^

@tylercb 가 나를 위해 일했습니다.

+1
이 오류는 openshift 환경에서 발생했습니다.

문제를 해결하기 위해 수행한 작업을 정확히 문서화하면 유용할 수 있다고 생각했습니다. 이것은 단순히 위의 다양한 게시물을 간단한 게시물로 조합한 것이므로 이 문제를 찾는 다른 사람은 잠재적인 솔루션을 쉽게 얻을 수 있습니다. 나는 노력을 인정하지 않습니다.

우리는 달리고 있다

  1. 우분투 14.04 LTS 서버,
  2. nginx 버전: nginx/1.4.6(Ubuntu)을 역방향 프록시 및 SSL 게이트웨이로 사용합니다.
  3. 우리는 Apache가 전혀 없습니다. 시스템에서 삭제되었습니다.
  4. nginx v0.10.25 뒤에서 실행되는 node.js 서버가 있습니다. 이것은 포트 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.

다음과 같이 읽도록 /etc/nginx/sites-enabled/default의 nginx 파일을 업데이트했습니다. (도메인 이름을 제외했습니다)

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. proxy_http_버전 1.1;
  2. proxy_set_header 업그레이드 $http_upgrade;
    3.proxy_set_header 연결 "업그레이드";

우리가 이미 그랬듯이

  1. proxy_set_header 호스트 $host;
  2. proxy_pass http://127.0.0.1 :4001;

이것이 도움이 되었기를 바랍니다.

도와 주셔서 감사합니다,

CAS(클래식 형식이 아님)로 인증할 때도 동일한 문제가 있고 LetEncrypt SSL과 함께 Apache를 프록시로 사용하고 있습니다. 설정할 특정 구성이 있습니까?

AWS Elastic BeanStalk에 Node.js 앱을 배포하려고 합니다.
.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 - Elastic Bean과 함께 아파치 서버와 ELB를 사용하고 있습니다.
당신이 제공한 코드를 어디에 넣어야 합니까?
감사 해요!

Elastic Bean에 대한 단서가 없지만 게시한 코드 조각은 Apache 호스트 파일로 이동합니다.

@tylercb 감사합니다! 그것은 나를 위해 일했습니다 ~

동일한 문제에 직면하는 nginx를 사용하지 않는 사람이 있습니까?

예, Elastic Load Balancer가 없는 단일 서버(노드 및 nginx)에서 Elastic Beanstalk를 사용하여 동일한 문제에 직면하고 있습니다.
http/https에서 ssl/tls로 변경하는 방법을 모르겠습니다.

여기 HAProxy와 동일한 문제

나를 위해 일했다. 감사 해요. 그리고 당신은 순서에주의를 기울여야합니다

proxy_set_header   Upgrade $http_upgrade;
proxy_set_header   Connection "upgrade";

예, 이것은 저에게도 해주었습니다.

나는 또한이 문제에 직면 해 있습니다. 400 오류가 발생하더라도 클라이언트와 서버 간의 웹 소켓 통신은 정상입니다. 이것은 우리의 개발 환경에 있습니다.

누군가 이것이 프로덕션 환경에서 문제가 될 것인지 말해 줄 수 있습니까?

참고: io.sails.url이 https가 아닌 경우 Postgres 애드온을 사용하여 Heroku에서 호스팅되는 socket.io를 사용하여 sail 백엔드에 연결하면 브라우저에서 이 오류가 발생합니다. 매우 구체적인 경우지만 이것이 Google에서 검색하는 동일한 스택을 가진 모든 사람에게 도움이 되기를 바랍니다.

헤이 여러분,

내 로컬 호스트 컴퓨터에서도 동일한 문제에 직면하고 있습니다. 우리는 python-flask를 서버로 사용하고 HTML/CSS/JS를 프론트엔드로 사용하고 있습니다.

우리가 사용한 Websocket Server와 연결하기 위해 Frontend에서
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 서버 = require('http').Server(앱);
var io = require('socket.io')(서버);
var WebRTC = 요구('../../');
app.use(express.static(__dirname));
var io = require('socket.io')(서버);

두 번째 "require('socket.io')"를 주석 처리하면 400 오류 메시지가 사라집니다.

이유에 대해서는 더 파고들 필요가 있지만... 앱이 동일한 연결을 두 번 시도하는지 확인할 수 있습니다.

안녕하세요 여러분, 이 토론이 한동안 진행되고 있다는 것을 알고 있으며 Application Load Balancer와 함께 AWS EBS를 사용하여 이 문제를 해결한 리소스를 게시하고 싶었습니다.

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

이것이 도움이 되기를 바랍니다.

트래비스

etherpad-lite를 사용할 때도 같은 문제가 있습니다.
Apache ProxyPass 문제를 해결하는 방법을 찾았습니다.
Apache http 2.2를 사용하고 있습니다. http 2.4 wstunnel 모듈의 backprot을 사용하므로 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;
저장하고 노드를 다시 시작하십시오.

둘째, 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>

`

아파치 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

또한 포트 80을 통한 HTTP 대신 포트 80을 통한 TCP를 사용하도록 탄력적 로드 밸런서를 조정해야 했습니다.

여러 노드에서 ProxyPass 지시문을 사용할 수 있습니까? 나는 https://github.com/socketio/socket.io/pull/2819 에 대해 RewriteRule 를 사용하게 되었습니다.

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' 'polling' 또는 'xhr-polling'과 함께 배열에 포함시키면 어떻게 될까요? 제공된 예제에 감사드립니다.

@fott1 기본값은 실제로 ['polling', 'websocket'] ( ref )입니다.

그러나 polling ( websocket 와 달리 ) 전송에서는 모든 요청이 동일한 socket.io 서버로 라우팅되어야 하므로 올바른 nginx 구성을 사용해야 합니다.

@darrachequesne 즉, 여러 서버 인스턴스가 있는 경우 모든 요청을 동일한 인스턴스로 라우팅해야 합니까? 내가 틀렸다면 정정하십시오. 팁 주셔서 감사합니다.

@fott1 네 맞습니다. 설명은 다음과 같습니다. https://socket.io/docs/using-multiple-nodes/

FWIW - 내 로컬에서 이것을 얻고 있었습니다(nginx 없음, 프록시 없음). socket.io를 사용하면 클라이언트와 서버 모두에서 첫 번째 웹 소켓으로 전송을 명시적으로 지정한 다음 폴링해야 합니다. 그것이 기본값이 아닌 이유를 모르겠습니다. 아니면 내가 잘못하고있는 것일 수도 있습니다.

우리의 원래 문제는 websocket 이전에 폴링이 있었고 순서가 중요하다는 것을 깨닫지 못했습니다.

원래 설정:
섬기는 사람:
io.set('transports', ['polling', 'websocket']);
고객:
var socket = io.connect(server, { reconnect: true });

우리는 클라이언트가 폴링 중임을 깨달았고 이를 옵션으로 제거했습니다. 그런 다음 모든 것이 실패하기 시작했고 400개의 잘못된 요청을 받았습니다.

그래서 마침내 우리는 클라이언트와 서버 모두에서 순서를 지정해야 한다는 것을 알아냈고, 지정하지 않으면 클라이언트는 바로 폴링으로 이동합니다. 이는 저에게 거의 의미가 없습니다. 기본적으로 websocket이 먼저라고 생각할 것입니다.

고치다:
섬기는 사람:
io.set('transports', ['websocket', 'polling']);
고객:
var socket = io.connect(server, { reconnect: true, transports: ['websocket', 'polling'] });

다시 말하지만, { 'transports': ['websocket', 'polling'] } 를 사용하면 웹 소켓 연결을 설정할 수 없을 때 롱 폴링에 대한 폴백이 없음을 의미합니다.

해당 문제를 종료하고 필요한 경우 다시 열어주세요.

저는 이전 제안과 유사한 위치 설정 으로 Elastic Beanstalk의 기본 nginx 구성을 "확장" 하는 접근 방식을 취했습니다. 다음과 같이 디렉토리 구조를 만듭니다.

 ~/작업 공간/내 앱/
 |-- .ebextensions
 | `-- nginx
 | `-- conf.d
 | `-- myconf.conf
 `-- web.jar

여기서 myconf.conf , 이름이 .conf 로 끝나는 한 임의의 이름은 다음을 포함합니다.

 서버 {
 위치 / {
 proxy_pass http://127.0.0.1:5000;
 proxy_http_버전 1.1;
 proxy_set_header 업그레이드 $http_upgrade;
 proxy_set_header 연결 "업그레이드";
 proxy_set_header 호스트 $host;
 }
 }

필요에 따라 포트 번호를 조정하십시오.

{ transports: ['polling'] } 만 추가하여 이 문제를 해결했습니다.

_

var 소켓 = io.connect(서버, {전송: ['폴링']});

_

@hyewon330 실제로 _해결_하지 않았다면 외모로 😉 애초에 websockets를 사용하지 않도록 socket.io를 구성했습니다. 물론 오류 메시지는 사라졌지만 이제 클라이언트와 서버 간의 연결이 웹 소켓을 지원하더라도 socket.io가 폴링을 사용하도록 강제하고 있습니다. 이것이 귀하의 응용 프로그램에 중요한지 확실하지 않지만 단지 당신이 알고 있는지 확인하고 싶었습니다 👌

Nginx 를 사용하는 사람은 @tylercb 솔루션이 완벽하게 작동합니다.

이 솔루션은 반짝이는 앱 문제를 해결했습니다. 지사.

@tylercb @rudolfschmidt @juanjoLenero @rwillett @cpres 안녕하세요, 귀하의 방법을 사용하지만 저에게는 효과가 없습니다. 8080이 아닌 다른 포트를 사용하기 때문에 의심됩니다. 예를 들어, 내 앱은 IP 170.8.8.8 모니터링 포트 5000을 사용하여 시스템 A에 배치되고 IP 170.8.8.2도 모니터링 포트 5000을 사용하는 시스템 B에 nginx를 넣었습니다. 그래서 저는 A의 IP:5000으로 건너뛰는 B의 IP:5000을 방문하고 싶습니다. 아래는 머신 B의 내 nginx 구성입니다.

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>

성공적으로 연결했음에도 불구하고 다음과 같은 동일한 오류가 계속 발생합니다.

'ws:// localhost:3000/socket.io/?EIO=3&transport=websocket&sid=EWl2jAgb5dOGXwScAAAB '에 대한 WebSocket 연결 실패: WebSocket 핸드셰이크 중 오류: 예기치 않은 응답 코드: 400

브라우저 콘솔을 볼 때 오류는 websocket.js의 112행을 가리키며 다음과 같이 표시됩니다.

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가 두 번 필요하지 않은지 확인하십시오. www/bin의 socket.io 설정을 app.js로 옮기고 실수로 이 오류를 일으킨 저장소에 require socket.io를 남겼습니다.

Socket.io 클라이언트에 {transports: ['websocket']} 옵션을 추가하기만 하면 됩니다.

이렇게 봐.

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

socket.io 서버의 @spookyUnknownUser는 한 번만 필요합니다.

@prapansak 클라이언트는 window.onload 함수 내에서 ES6 가져오기가 허용되지 않는 간단한 자바스크립트 파일입니다. 그러나 사용 방법 섹션을 따릅니다.
<script src="/socket.io/socket.io.js"></script>

그리고 제안한대로 소켓을 호출 할 때 :
const socket = io('http://localhost:5000', {transports: ['websocket']})

이 오류가 발생합니다: 'ws:// localhost:1337/socket.io/?EIO=3&transport=websocket '에 대한 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 또는 아파치 구성을 변경하지 않고도 문제를 해결할 수 있었습니다.

이 문제를 해결하기 위해 변경한 사항: https 대신 443에서 SSL을 내 애플리케이션 포트로 허용하고 내 보안 그룹에서 포트 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;
proxy_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 연결 "업그레이드";

작은 따옴표를 사용하여 이 메시지를 받았지만 큰 따옴표를 사용하여 해결했습니다.

약 1시간의 문제 해결 후 엔드포인트를 클러스터로 실행하는 경우 몇 가지 추가 구성이 필요할 수 있습니다.

여기를 참조하십시오

tylercb 솔루션이 저에게 효과적이었습니다(NgInx). 감사 해요!

우리의 핵심은 @tylercb 솔루션의 proxy_http_version 1.1;

많은 의견에 따라 내 서버에서 NginX 구성을 편집했습니다.
그러나 부분적으로 작동합니다. 처음에는 서버를 다시 시작한 후 제대로 작동하지 않습니다. 대부분 하드 새로 고침으로. 나중에 더 잘 작동하며 때로는 하드 새로 고침이 필요합니다.
sails lift 로 로컬에서 작동합니다.
그러나 로컬에서 sails lift --prod 를 사용하는 경우 동일한 결과가 나타납니다. 해당 소켓을 연결할 수 없고 400 잘못된 응답이 나타납니다. 그러나 몇 번의 시도 후에 다시 안정적입니다.

이것은 여전히 ​​해결되지 않은 것 같습니다. 왜 우리가 이것을 가지고 있는지 최종 솔루션을 찾지 못했습니다.

설명서에 다양한 구성을 추가했습니다. https://socket.io/docs/using-multiple-nodes/

개선을 위한 모든 제안을 환영합니다! => https://github.com/socketio/socket.io-website

나는이 문제에 직면했지만 여전히 nginx를 비활성화하는 오류가 발생합니다. 마지막으로 Express의 express-status-monitor 미들웨어로 인해 문제가 발생하여 WebSocket의 첫 번째(요청) 핸드셰이크에서 HTTP 호출이 실패하게 됩니다.

미들웨어와 WebSocket이 잘 작동하는 것을 비활성화하려고 합니다.

악수하는 동안 400을 얻는 데는 몇 가지 이유가 있습니다. 다음은 시도할 수 있는 몇 가지 사항입니다.

  1. (ufw/Other) 방화벽 및 (AWS/Google 클라우드/기타) 콘솔 설정에서 443 활성화
  2. nodejs 서버에서 TLS를 활성화하지 마십시오. nginx로 해보세요.
  3. 다음 nginx 구성 사용
    참고: 이것은 socket.io 연결이 이미 작동하지만 웹 소켓 대신 긴 폴링을 사용하는 경우에만 작동합니다. 아래 코드를 추가하면 websocket을 사용하기 시작합니다.
        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이 발생했습니다. 그것은 일종의 어리석은 오류이지만... 그건 내 것이었습니다.

애플리케이션 로드 밸런서에서 고정 세션을 활성화해야 합니다(클래식 로드 밸런서는 사용하지 마십시오). 고정 세션을 사용하지 않으면 무작위로 400개의 오류가 발생합니다.

폴링에서 웹 소켓으로의 업그레이드를 시도할 때 로드 밸런서가 이 소켓 ID를 만난 적이 없는 서버로 업그레이드 요청의 균형을 맞추고 400 오류를 발생시킬 수 있기 때문입니다. 자세한 내용은 https://socket.io/docs/using-multiple-nodes/ 를 참조하세요.

또한 Elastic beanstalk를 사용하는 경우 .ebextensions 폴더에 다음 websocket.config 파일을 추가하여 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도 사용하기 때문에 구글링했습니다. 해결책은 이 부분을 추가하는 것입니다

proxy_http_버전 1.1;
proxy_set_header 업그레이드 $http_upgrade;
proxy_set_header 연결 "업그레이드";
proxy_set_header 호스트 $host;

언급한 tylercb와 같은 nginx 구성 파일에 추가합니다.

따라서 최소한 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 구성 등)를 사용하여 해결할 수 있지만 많은 사용자는 이러한 설정에 액세스할 수 없으므로 일종의 이것에 socket.io에서 수정 ...

아무도?

@deemeetree
사이트의 "세션 ID를 알 수 없음" 오류 메시지로 인해 가능한 것으로 보이는 여러 노드를 사용하는 경우 StackOverflow (https://stackoverflow.com/a/53163917/6271092) 에 대한 내 답변을 살펴봐야 합니다.

간단히 말해서 socket.io는 사이트 (https://socket.io/docs/using-multiple-nodes/) 에서 말하는 것처럼 ,

다른 프로세스나 시스템 간에 연결 로드를 분산하려는 경우 특정 세션 ID와 연결된 요청이 해당 요청을 시작한 프로세스에 연결되도록 해야 합니다.

이는 "소켓"의 수명 동안 여러 요청을 실행하는 XHR 폴링 또는 JSONP 폴링과 같은 특정 전송 때문입니다. 고정 밸런싱을 활성화하지 않으면 두려운 결과가 발생합니다.

Error during WebSocket handshake: Unexpected response code: 400

따라서 다른 노드에서 작동하는 여러 소켓을 가질 수 없습니다. 말씀대로 서버를 재구성하십시오. Express의 경우 다음과 같이 포트를 구성합니다.
parseInt(your_port) + parseInt(process.env.NODE_APP_INSTANCE);

도움이 되기를 바랍니다.

Windows Server 2008R2(프록시 없음, IIS 없음)에서 호스팅되는 내 앱에 직접 연결하는 것과 동일한 오류가 발생했습니다. 그 사이에는 멍청한 중간 하드웨어만 있을 뿐입니다.

Window Server 2016에서 동일한 문제에 직면하고 있습니다. 수정 사항을 언급해 주십시오. 감사 해요

나는 꽤 오랫동안이 문제에 직면 해 왔습니다. 정보 아시는 분 계시면 도와주세요. 아파치 서버를 사용하고 있습니다.

어떤 단서? dev에서는 훌륭하게 작동하지만 SSL에서는 동일한 문제입니다.

PM2 노드 클러스터 모드 사용: 4 x 1

아파치 프록시 사용, 여전히 단서 없음

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이 범인입니다. 물론 이렇게 하면 문제가 해결됩니다.
그렇지 않은 경우

역방향 프록시 구성에서 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를 사용하는 데 여전히 문제가 있는 사람이 있다면 @slaveofcode 가 언급한 것처럼 문제가 express-status-monitor 일 수 있습니다. 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

현재 EKS 클러스터에 대한 Linkerd 대시보드(서비스 메시) 노출과 관련하여 이 문제에 직면하고 있습니다. 우리는 nginx를 사용하므로 현재로서는 어떻게 빠져나갈지 정확히 모릅니다.

@andrzj 세상에, 당신은 방금 저를 구했습니다.

같은 문제가 있었지만 내 앱은 nginx 뒤에 있습니다. 내 Nginx 구성을 변경하면 오류가 제거되었습니다.

위치 / {
proxy_pass http://localhost :8080;
proxy_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 핸드셰이크 오류가 발생합니다. 그러나 저는 AWS에서 Application Load Balancer를 사용 중이며 대상 그룹으로 전달하는 443 수신기와 :80 대상 그룹으로 설정했습니다.

NGINX conf 파일:

`서버 {

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()

수동 인스턴스 생성(express 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;
proxy_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 를 사용하기 시작할 때 이 문제를 해결하기 위해 밤새도록 보냈습니다. 항상 400 connection stopped before establish 라고 표시됩니다.

불과 몇 분 전에 이에 대한 해결책을 찾았습니다.

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 Access #$을 허용하려면 서버 Cross-Origin Controls'*' 로 설정되어 있는지 확인하십시오.

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도 사용하기 때문에 구글링했습니다. 해결책은 이 부분을 추가하는 것입니다

proxy_http_버전 1.1;
proxy_set_header 업그레이드 $http_upgrade;
proxy_set_header 연결 "업그레이드";
proxy_set_header 호스트 $host;

언급한 tylercb와 같은 nginx 구성 파일에 추가합니다.

나를 위해 잘 일했습니다 감사합니다!

저처럼 Elastic Beanstalk를 사용하여 node-server를 생성하신다면,
환경을 만드는 동안 구성에서 어떤 프록시 서버를 사용할지 묻는 메시지가 표시됩니다. nginx가 미리 채워져 있거나 기본 설정되어 있습니다.
해당 프록시 서버를 없음으로 설정한 다음 계속해서 내 서버를 생성했습니다. Elastic Beanstalk를 사용하여 프록시 서버가 기본적으로 nginx로 설정된 노드 서버를 생성하고 있었습니다.
프록시 서버 설정 오류이기 때문입니다. 프록시 서버를 제거한 후 오류가 사라졌습니다.

몇 시간 동안 인터넷 검색을 했지만 nodejs 앱이 있고 nginx가 없기 때문에 위의 솔루션 중 어느 것도 적용되지 않았습니다.

우리가 이 문제를 해결한 방법은 모든 트래픽을 노드로 직접 전달하기 위해 컨테이너 -> 로드 밸런서 설정에서 nginx를 비활성화하는 것이었습니다.

몇 시간 동안 인터넷 검색을 했지만 nodejs 앱이 있고 nginx가 없기 때문에 위의 솔루션 중 어느 것도 적용되지 않았습니다.

우리가 이 문제를 해결한 방법은 모든 트래픽을 노드로 직접 전달하기 위해 컨테이너 -> 로드 밸런서 설정에서 nginx를 비활성화하는 것이었습니다.

당신은 그렇게 않았다 방법?

구성 > 로드 밸런서로 이동하면 프록시 서버에 대한 드롭다운을 찾을 수 있습니다. nginx, Apache를 사용하거나 노드 앱에 대한 모든 연결을 통과하도록 "없음"으로 설정할 수 있습니다.

로드 밸런서가 있는 환경을 생성하는 경우에만 표시되며 단일 인스턴스에서는 작동하지 않습니다.

편집: 내 원래 의견은 Elastic Beanstalk를 참조했습니다.

같은 문제가 있었지만 내 앱은 nginx 뒤에 있습니다. 내 Nginx 구성을 변경하면 오류가 제거되었습니다.

위치 / {
proxy_pass http://localhost :8080;
proxy_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-server를 클라이언트 프로젝트와 Redis-server 사이에 분리된 서버로 사용하는 사람들을 위한 것입니다.

여기 의 링크 를 따르 십시오 .

감사 해요

나는이 문제가 있었다. 내 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);
      }
    });
  }

AWS Elastic Beanstalk(Nginx 프록시) 에서 실행되는 Node.js/Express와 함께 NUXT.js와 동일한 문제가 발생했습니다. 이것을 알아내는 데 며칠이 걸렸습니다. 제 독서 포인트를 공유하겠습니다. 누군가는 유용하다고 생각할 것입니다.

내 환경은 SSL을 사용하는 https용 80 및 https용 443의 두 포트가 있는 Application Load Balancer 에 있습니다.

위의 답변을 조합하여 @tylercbAWS 의 공식 문서 및 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 구성

그게 다야 꽤 깁니다. 죄송합니다. 행운을 빕니다.

Angular .net 코어에 대한 우분투 및 ngnix 서버의 변경 사항 아래에서 저를 위해 일하고 있습니다.

위치 / {
proxy_pass http://localhost :8080;
proxy_http_버전 1.1;
proxy_set_header 업그레이드 $http_upgrade;
proxy_set_header 연결 "업그레이드";
proxy_set_header 호스트 $host;
}

Nodejs + Express를 사용하는 데 여전히 문제가 있는 사람이 있다면 @slaveofcode 가 언급한 것처럼 문제가 express-status-monitor 일 수 있습니다. 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;
proxy_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 등급