Socket.io: خطأ أثناء اتصال WebSocket: رمز استجابة غير متوقع: 400

تم إنشاؤها على ١٤ يناير ٢٠١٥  ·  129تعليقات  ·  مصدر: socketio/socket.io

لا يمكنني العثور على حل ، لقد تلقيت هذا الخطأ في وحدة تحكم المتصفح:
فشل اتصال WebSocket بـ 'ws: //.../socket.io/؟ EIO = 2 & transport = websocket & sid = p3af7ZNfvogtq6tAAAG0': خطأ أثناء اتصال WebSocket: رمز استجابة غير متوقع: 400.

هافا أي نصيحة؟

التعليق الأكثر فائدة

واجهت نفس المشكلة ، تطبيقي خلف nginx. أدى إجراء هذه التغييرات على تكوين Nginx إلى إزالة الخطأ.

موقعك / {
proxy_pass http: // localhost : 8080 ؛
proxy_http_version 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-unuable-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 ؛
proxy_http_version 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 لإرسال اتصالات إلى العقدة.

نفس الشيء هنا - رسالة وظيفية كاملة ولكن خطأ في أدوات التطوير. قرأت في مكان آخر أنه متعلق بإصدار Apache - باستخدام 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؟ حاليًا ، تدعم خطة المؤسسة الخاصة بهم WebSockets فقط.

حل بالنسبة لي. كان بسبب عنوان socket.io خاطئ في تكوين nginx ، لم يكن مطابقًا للمسار باستخدام مقبس الويب.

لقد بحثت في Google لأنني واجهت نفس المشكلة وأستخدم nginx أيضًا. الحل هو إضافة هذا الجزء

proxy_http_version 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 لا يدعم Websockets على الخطة المجانية. لقد قمت بإيقاف تشغيل 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) لم يتم إعداده بشكل صحيح لقبول رأس الترقية. إصلاح tylercb منذ حوالي عام تم إصلاحه ^

tylercb عملت لي.

+1
حدث هذا الخطأ في بيئة النقل المفتوح

اعتقدت أنه قد يكون مفيدًا إذا قمت بتوثيق ما فعلته بالضبط لحل المشكلة. هذا مجرد مزيج من المنشورات المختلفة المذكورة أعلاه في منشور بسيط حتى يتمكن أي شخص آخر يجد هذه المشكلة من الحصول على حل محتمل بسهولة. أنا لا أنسب إلى العمل الشاق.

نحن نركض

  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. proxy_http_version 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 (ليس بالشكل الكلاسيكي) ، وأنا أستخدم 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 - أنا أستخدم خادم اباتشي و 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 ، فإن اتصال websocket بين العميل والخادم جيد. هذا في بيئتنا التنموية.

هل يمكن لأي شخص أن يخبرني ما إذا كانت هذه ستكون مشكلة في بيئة الإنتاج.

لمعلوماتك: سيؤدي الاتصال بخلفية الأشرعة باستخدام 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 = يتطلب ('http'). Server (app) ؛
var io = يتطلب ('socket.io') (خادم) ؛
var WebRTC = يتطلب ('../../') ،
app.use (express.static (__ dirname)) ؛
var io = يتطلب ('socket.io') (خادم) ؛

بعد الخروج من التعليق ، تختفي رسالة الخطأ 400 الثانية "تتطلب ('socket.io')".

بحاجة لمزيد من البحث عن السبب ... ولكن يمكنك التحقق مما إذا كان تطبيقك يحاول إجراء نفس الاتصال مرتين.

مرحبًا يا رفاق ، أعلم أن هذه المناقشة كانت مستمرة منذ فترة وأردت نشر مورد حل هذه المشكلة بالنسبة لي باستخدام AWS EBS مع Application Load Balancer.

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

تأمل أن يساعد هذا.

ترافيس

لدي نفس المشكلة عندما أستخدم etherpad-lite.
لقد وجدت طريقة لإصلاح مشكلة Apache ProxyPass.
أنا أستخدم Apache http 2.2 يستخدم backprot من وحدة http 2.4 wstunnel لذا أعتقد أنه يمكن إصلاح الإصدار 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>

"

أعد تشغيل apache httpd ، واستمتع ب ~

بالنسبة إلى Apache ، اتبع cpres answer ، فهو يعمل. أسيوط بلدي

<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 ، حاول تحديث سياسة الأمان الخاصة بك ، فقد واجهت نفس المشكلة على الرغم من أنها كانت تعمل بشكل جيد في الإعداد الدقيق لموقع ويب آخر ولكن لاحظت أن سياسة الأمان كانت متأخرة حوالي عام واحد. يبدو أن تحديثه إلى إصدار أحدث قد أدى إلى حل المشكلة.

بعد تكوين nginx والعميل ، كنت لا أزال أعاني من أجل إيجاد الحل الدقيق.
لكن visibleajay أدخلت هذا التعليق وأدركت أنني لم أستخدم الجزء {'transports': ['websocket']} في الأمر io.connect.

لذلك بالنسبة لأي شخص قد يكون في نفس المشكلة ،
var socket = io.connect('https://server.com/socket.io-path-here', { 'transports': ['websocket'] });

قام بالمهمة ، جنبًا إلى جنب مع تكوينات nginx الصحيحة.

@ fott1 يرجى العلم أن استخدام { 'transports': ['websocket'] } يعني عدم وجود رجوع إلى الاقتراع الطويل عندما يتعذر إنشاء اتصال websocket.

المثال الكامل مع nginx: https://github.com/socketio/socket.io/tree/master/examples/cluster-nginx

darrachequesne أعتقد أنك على حق ، ماذا لو قمت بتضمين "الاستقصاء" أو "الاستقصاء" في المصفوفة مع "Websocket"؟ شكرا لك على المثال المقدم.

@ fott1 ، الافتراضي هو ['polling', 'websocket'] ( المرجع ).

لكنك ستحتاج إلى استخدام تكوين nginx الصحيح ، نظرًا لأن النقل polling (على عكس websocket ) يتطلب توجيه كل طلب إلى نفس خادم socket.io.

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 طلب سيئ.

لذا فقد توصلنا أخيرًا إلى أنه يتعين عليك تحديد الترتيب في كل من العميل والخادم ، وإذا لم تقم بذلك ، فسيذهب العميل مباشرة إلى الاقتراع ، وهو أمر لا معنى له بالنسبة لي. كنت تعتقد أنه سيكون الافتراضي مقبس الويب أولاً.

يصلح:
الخادم:
io.set('transports', ['websocket', 'polling']);
عميل:
var socket = io.connect(server, { reconnect: true, transports: ['websocket', 'polling'] });

مرة أخرى ، يرجى الانتباه إلى أن استخدام { 'transports': ['websocket', 'polling'] } يعني عدم وجود رجوع إلى الاقتراع الطويل عندما يتعذر إنشاء اتصال websocket.

دعنا نغلق هذه المشكلة ، يرجى إعادة فتحها إذا لزم الأمر.

لقد اتخذت نهج "تمديد" تكوين nginx الافتراضي لـ Elastic Beanstalk مع إعدادات الموقع المشابهة لبعض الاقتراحات السابقة. قم بإنشاء بنية دليل مثل:

 ~ / workspace / my-app /
 | - ملحقات
 | "- nginx
 | "- أسيوط
 | "- myconf.conf
 "- web.jar

حيث myconf.conf ، واسمه تعسفي طالما أنه ينتهي بـ .conf يحتوي على ما يلي:

 الخادم {
 موقعك / {
 proxy_pass http://127.0.0.1:5000 ؛
 proxy_http_version 1.1 ؛
 proxy_set_header ترقية $ http_upgrade؛
 proxy_set_header اتصال "ترقية" ؛
 proxy_set_header المضيف $ host؛
 }
 }

تأكد من ضبط رقم المنفذ حسب احتياجاتك.

لقد قمت بحل هذه المشكلة بإضافة {النقل: ['الاستقصاء']} فقط.

_

var socket = io.connect (الخادم ، {النقل: ['الاستقصاء']}) ؛

_

@ hyewon330 بالمظهر إذا لم تكن قد قمت بالفعل بحلها 😉 لقد قمت ببساطة بتكوين socket.io حتى لا تحاول استخدام مآخذ الويب في المقام الأول. بالتأكيد ، اختفت رسالة الخطأ ، لكنك الآن تجبر socket.io على استخدام الاستقصاء حتى إذا كان الاتصال بين العميل والخادم _سوف يدعم مآخذ الويب. لست متأكدًا مما إذا كان هذا مهمًا لتطبيقك ، أردت فقط التأكد من أنك تعرف 👌

لأي شخص يستخدم Nginx ، يعمل حل tylercb بشكل مثالي.

هذا الحل أصلح مشكلتي مع التطبيقات اللامعة. محافظ.

tylercbrudolfschmidtjuanjoLenerorwillettcpres مرحبا ، أنا أستخدم طريقتك لكنها لا تعمل بالنسبة لي. أشك إذا كنت أستخدم منفذًا آخر بدلاً من 8080. على سبيل المثال ، تم وضع تطبيقي في الجهاز A مع IP 170.8.8.8 منفذ المراقبة 5000 ، ووضعت nginx في الجهاز B مع IP 170.8.8.2 أيضًا مراقبة المنفذ 5000. لذلك أنا تريد زيارة IP: 5000 in B الذي يتخطى IP: 5000 in 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 ، العميل عبارة عن ملف جافا سكريبت بسيط ، داخل وظيفة 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 ؛
proxy_http_version 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-website

أنا فقط أواجه هذه المشكلة وما زلت أتلقى خطأ حتى تعطيل nginx الخاص بي. أخيرًا المشكلة بسبب express-status-monitor الوسيطة على express ، يؤدي هذا إلى فشل استدعاء HTTP عند مصافحة (الطلب) الأولى لـ WebSocket.

أحاول تعطيل هذه البرامج الوسيطة ويعمل WebSocket بشكل جيد

هناك عدة أسباب وراء حصولك على 400 أثناء المصافحة. فيما يلي بعض الأشياء التي يمكن تجربتها

  1. قم بتمكين 443 في جدران الحماية (ufw / أخرى) بالإضافة إلى إعدادات وحدة التحكم (AWS / Google cloud / Other)
  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 خطأ عشوائيًا.

هذا لأنه عند محاولة الترقية من الاستقصاء إلى websocket ، فمن المحتمل أن يوازن موازن التحميل طلب الترقية إلى خادم لم يواجه معرّف المقبس هذا مطلقًا ويظهر الخطأ 400. مزيد من التفاصيل هنا: https://socket.io/docs/using-multiple-nodes/

أيضًا ، إذا كنت تستخدم شريط فاصولياء مرن ، فأضف ملف 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

لقد بحثت في Google لأنني واجهت نفس المشكلة وأستخدم nginx أيضًا. الحل هو إضافة هذا الجزء

proxy_http_version 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-unuable-re

يعاني العديد من المستخدمين من هذه المشكلة بسبب تكوين nginx وأثناء وجودك على الخوادم المخصصة ، يمكنك إصلاحها باستخدام الأفكار المذكورة أعلاه (تكوين nginx ، إلخ) لا يمتلك العديد من المستخدمين إمكانية الوصول إلى هذه الإعدادات ، لذلك سيكون من الرائع أن يكون لديك نوع من الإصلاح من sockets.io على هذا ...

لا أحد؟

تضمين التغريدة
إذا كنت تستخدم عقدًا متعددة تبدو لي ممكنة بسبب رسالة الخطأ على موقعك "معرّف الجلسة غير معروف" ، يجب أن تلقي نظرة على إجابتي على StackOverflow (https://stackoverflow.com/a/53163917/6271092) .

لتكون قصيرًا ، socket.io كما يقولون على موقعهم (https://socket.io/docs/using-multiple-nodes/) ،

إذا كنت تخطط لتوزيع حمل الاتصالات بين العمليات أو الأجهزة المختلفة ، فيجب عليك التأكد من أن الطلبات المرتبطة بمعرف جلسة معين تتصل بالعملية التي أنشأتها.

ويرجع ذلك إلى بعض وسائل النقل مثل XHR Polling أو JSONP Polling التي تعتمد على إطلاق عدة طلبات خلال عمر "المقبس". سيؤدي الفشل في تمكين التوازن اللزج إلى:

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 ، يرجى ذكر الإصلاح الخاص بك. شكرا

لقد كنت أواجه هذه المشكلة منذ بعض الوقت. إذا كان لدى أي شخص أي معلومات الرجاء المساعدة. أنا أستخدم خادم اباتشي.

أي فكرة؟ يعمل بشكل رائع على التطوير ولكن نفس المشكلة على SSL.

استخدام وضع PM2 Node Cluster: 4 × 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؟ شكرا!

هذا التكوين موجود في ملف site.conf الذي تم تمكينه من قِبل المواقع ، ولكن يجب أن يعمل في htaccess أيضًا afaik

كل ما يمكنني قوله ، SSL هو السبب هنا :) تعطيل ، وضع SSL المرن Cloudflare والانتقال إلى وضع FULL (STRICT). بالتأكيد سيؤدي هذا إلى حل المشكلة ،
ان لم،

استخدم المضيف المحلي: المنفذ في تكوين الوكيل العكسي.

لأي شخص هنا يستخدم 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 OMG يا رجل ، لقد أنقذتني للتو.

واجهت نفس المشكلة ، تطبيقي خلف nginx. أدى إجراء هذه التغييرات على تكوين Nginx إلى إزالة الخطأ.

موقعك / {
proxy_pass http: // localhost : 8080 ؛
proxy_http_version 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 (في الوقت الحالي ، لم تجرِ تجربة التكوين أعلاه حتى الآن).
  • على شجرة الفاصولياء المرنة: تحميل الموازن على النحو التالي:
  • على Node / Express: 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 Target Group و 443 مستمع يقوم بإعادة التوجيه إلى Target Group.

ملف 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()

إنشاء مثيل يدوي (بدون التعبير عن 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_version 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. Cloudflare

في علامة التبويب 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-config-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/

لقد بحثت في Google لأنني واجهت نفس المشكلة وأستخدم nginx أيضًا. الحل هو إضافة هذا الجزء

proxy_http_version 1.1 ؛
proxy_set_header ترقية $ http_upgrade؛
proxy_set_header اتصال "ترقية" ؛
proxy_set_header المضيف $ host؛

في ملف تكوين nginx مثل tylercb المذكور.

عملت معي بشكل جيد شكرا لك!

إذا كنت تستخدم Elastic Beanstalk مثلي تمامًا لإنشاء خادم عقدة ،
أثناء إنشاء البيئة ، يُطلب منا في التكوينات استخدام خادم وكيل. يتم فيه ملء nginx مسبقًا أو تعيينه افتراضيًا.
لقد قمت بتعيين هذا الخادم الوكيل على لا شيء ثم تابعت إنشاء الخادم الخاص بي. كنت أستخدم Elastic Beanstalk لإنشاء خادم عقدة حيث تم تعيين الخادم الوكيل افتراضيًا على nginx.
لأنه خطأ في تكوين الخادم الوكيل. بعد إزالة أي خادم وكيل ، اختفى الخطأ.

تم استخدام googling لساعات ولم يتم تطبيق أي من الحلول المذكورة أعلاه علينا نظرًا لأن لدينا للتو تطبيق nodejs ولا يوجد nginx.

كانت الطريقة التي حلنا بها هذا هي فقط تعطيل nginx من الحاوية -> إعدادات موازن التحميل لتمرير كل حركة المرور مباشرة إلى العقدة.

تم استخدام googling لساعات ولم يتم تطبيق أي من الحلول المذكورة أعلاه علينا نظرًا لأن لدينا للتو تطبيق nodejs ولا يوجد nginx.

كانت الطريقة التي حلنا بها هذا هي فقط تعطيل nginx من الحاوية -> إعدادات موازن التحميل لتمرير كل حركة المرور مباشرة إلى العقدة.

كيف فعلت ذلك؟

إذا انتقلت إلى Configuration> Load Balancer ، يمكنك العثور على قائمة منسدلة للخادم الوكيل ، يمكنك استخدام nginx أو Apache أو ضبطها على "لا شيء" لتمرير جميع الاتصالات إلى تطبيق العقدة.

يظهر هذا فقط إذا قمت بإنشاء بيئة باستخدام موازن تحميل ، ولا يعمل في حالات فردية

تحرير: تمت إحالة تعليقي الأصلي إلى Elastic Beanstalk

واجهت نفس المشكلة ، تطبيقي خلف nginx. أدى إجراء هذه التغييرات على تكوين Nginx إلى إزالة الخطأ.

موقعك / {
proxy_pass http: // localhost : 8080 ؛
proxy_http_version 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.

الرجاء اتباع الرابط هنا .

شكرا

كان لدي هذه المشكلة. لم يساعد تحديث تهيئة 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 للنواة .net الزاوي

موقعك / {
proxy_pass http: // localhost : 8080 ؛
proxy_http_version 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 ؛
proxy_http_version 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 التقييمات