Socket.io: 1.0.0 قبل "معرف الجلسة غير معروف"

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

استجابة HTTP
{"code": 1 ، "message": "معرف الجلسة غير معروف"}

DEBUG = socket.io: *

socket.io: مقبس متصل بغرفة 2d1DHsPAtc1Sspm6AAAE + 0ms
socket.io: اتصال وارد للخادم بمعرف rwLW7JMBp6E4TyexAAAG + 3s
socket.io: اتصال العميل بمساحة الاسم / + 3s
socket.io: مساحة اسم إضافة مقبس إلى nsp / + 3s
socket.io: مقبس متصل - علبة كتابة + 3s
socket.io: مقبس الانضمام إلى الغرفة rwLW7JMBp6E4TyexAAAG + 0ms
socket.io: حزمة كتابة العميل {"type": 0، "nsp": "/"} + 1ms
socket.io: حزمة كتابة العميل {"type": 2، "data": ["news"، {"hello": "world"}]، "nsp": "/"} + 0ms
socket.io: مقبس متصل بالغرفة rwLW7JMBp6E4TyexAAAG + 1ms
socket.io: اتصال وارد للخادم مع معرف 03Izy4YOxaYm5-d-AAAH + 1s
socket.io: اتصال العميل بمساحة الاسم / + 1s
socket.io: مساحة اسم إضافة مقبس إلى nsp / + 1s
socket.io: المقبس متصل - علبة كتابة + 1s
socket.io: مقبس الانضمام إلى غرفة 03Izy4YOxaYm5-d-AAAH + 0ms
socket.io: حزمة كتابة العميل {"type": 0، "nsp": "/"} + 1ms
socket.io: حزمة كتابة العميل {"type": 2، "data": ["news"، {"hello": "world"}]، "nsp": "/"} + 0ms

ويتم فصل المقبس على الفور

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

بالنسبة لي ، كان ذلك مع nginx ssl http2 ، وكان الاستقصاء ، لذا فإن التكوين الجيد هو:

 const ioSocket = io('', {
      // Send auth token on connection, you will need to DI the Auth service above
      // 'query': 'token=' + Auth.getToken()
      path: '/socket.io',
      transports: ['websocket'],
      secure: true,
    });

ال 38 كومينتر

شكرا على الإبلاغ @ ceram1. هل يمكنك تكرار هذه المشكلة مع 1.0.2؟ إذا كان الأمر كذلك ، فسيكون من المثير للاهتمام رؤية سجلات تصحيح الأخطاء من جانب العميل أيضًا و / أو الحصول على بعض التعليمات البرمجية لإعادة إظهار المشكلة. سيساعد كثيرا. :)

آه .. آسف ... كان البريد في بريد عشوائي ... سأختبره قريبًا

+1
لقد لاحظنا ذلك في ظل معدل اتصال ثقيل على مجموعة مكونة من عقدة (مدعومة بمقبس socket.io-redis).

أهلا يا أصدقاء،
socket.io 1.0.6
المقبس

استجابة:
{"code": 1 ، "message": "معرف الجلسة غير معروف"}

فقط مع أكثر من مثيل واحد على Heroku.
في حالة واحدة ، كل شيء يعمل بشكل جيد (نحن نحبه) مع 2 أو أكثر من الحالات التي يفشل فيها. 400 خطأ.

التهيئة:
io = تتطلب ('socket.io') (مركب خادم) ؛

io.adapter(redisSocket({
    host: redisHost
    , port: redisPort
    , pubClient: pub
    , subClient: sub
}));

sub = redis.createClient (redisPort، redisHost، {return_buffers: true}) ؛
pub = redis.createClient (redisPort، redisHost، {return_buffers: true}) ؛
client = redis.createClient (redisPort، redisHost، {return_buffers: true}) ؛

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

شئ جديد هنا ؟؟

أنا في الواقع أواجه نفس المشكلة الآن. كل شيء يعمل بشكل جيد في حالة واحدة ، وحدث 400 خطأ عندما يكون هناك أكثر من مثيل واحد قيد التشغيل.

ملاحظة. منجم يعمل في الإصدار 1.0.6.

+1

حسنًا يا رفاق ، إذا كنت تريد تشغيل الكتلة ، فإن أسهل طريقة هي المضي قدمًا إلى مجموعة مقابس مكالمات المكتبة.
إنه يعتمد على engine.io رغم ذلك ، لكنه قريب بما يكفي لمقبس socket.io
https://github.com/TopCloud/socketcluster

+1 ، إذا قمت بتعيين أكثر من حالة واحدة بعد ELB ، فسوف أواجه هذه المشكلة.

+1

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

أنا أعرف ما هي المشكلة. جميع الطلبات مثل التجميع تستدعي في كل مرة نفس المثيل عن طريق المنفذ.
لكن في حالتي لا يعمل لأنني على heroku. ولا يدعم heroku الوصول إلى المثيل عن طريق المنفذ. يختار دائمًا المثيل من خلال موازن التحميل الخاص به.
المشكلة هنا:
socket.io/node_modules/engine.io/lib/server.js على وظيفة "التحقق" من وجود "عملاء" متغير موجود بشكل منفصل في كل حالة. لذلك إذا جاء الطلب إلى مثيل مختلف ، فسيتم إرجاع 400.

آه .. لم أتجمع في كود الاختبار. ربما هذا هو السبب في أنني لا أستطيع العودة مرة أخرى

هنا حل آخر لإصلاح هذه المشكلة. ومع ذلك ، من معظم حالات الاستخدام لنرى ، هذا الحل ليس جيدًا ...

أفضل حل توصلت إليه هو إعطاء كل مثيل (خادم مقبس) منفذًا مختلفًا وتخزين عنوان المثيل مع عدد العملاء المتصلين به في redis. ثم اطلب من العميل أن يسأل تطبيق عقدة منفصل (مدير مقبس) عن عنوان خادم مأخذ قبل الاتصال أو إعادة الاتصال. ثم يختار مدير المقبس خادم socket.io مع أقل عدد من الاتصالات. إنها ليست جميلة ولكنها تعمل ويمكن توسيع نطاقها.

https://github.com/Automattic/socket.io/issues/1636

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

http://socket.io/docs/using-multiple-nodes/

أنت بحاجة إلى ip_hash في تعريف خادم المنبع وبعض الترويسات.

dux التي عملت على Heroku؟ لا أعتقد أنه يمكننا تغيير تكوين nginx.

يو بي إس ، لم أكن أعرف أن هذا هو موضوع heroku الحصري. لا ، هذا هو حل خادم الواجهة الأمامية لـ Vanilla nginx.

إذا تمكن شخص ما من إيجاد حل لـ HEROKU ، فالرجاء نشره هنا سيكون مفيدًا جدًا :)

miklacko بعد الكثير من المحاولات والأخطاء التي انتهيت بها من هذا التكوين (ضع في اعتبارك أنه لم يكن لدي الوقت لاختبار ما إذا كانت الرسائل قد تمت مشاركتها بين المتصفحات. ولكن ما يمكنني اختباره هو أن لدي اتصال ثابت بين العميل والخادم مع 4.x سريع مجمع ومقبس 1.x.

صريح. js

var sio_redis = require('socket.io-redis'),
    url = require('url'),
    http = require('http'),
       // other imports... 

// Some express set up

// CookieParser should be above session
    app.use(cookieParser());

    var sessionStore = new mongoStore({
        db: db.connection.db,
        collection: config.sessionCollection
    });
    // Express MongoDB session storage
    var sessionMiddleware = session({
        secret: config.sessionSecret,
        store: sessionStore
    });

    app.use(sessionMiddleware);

    // Create Server and Socket.io
    var server = http.createServer(app);
    var sio = require('socket.io')(server);

    if(process.env.REDISCLOUD_URL){
        var redisURL = url.parse(process.env.REDISCLOUD_URL);
        redisURL.password = redisURL.auth.split(':')[1];
        var pub = require('redis').createClient(redisURL.port, redisURL.hostname, {auth_pass: redisURL.password, return_buffers: true});
        var sub = require('redis').createClient(redisURL.port, redisURL.hostname, {auth_pass: redisURL.password, return_buffers: true});
        sio.adapter(sio_redis({pubClient: pub, subClient: sub}));
    } else {
        sio.adapter(sio_redis({ host: 'localhost', port: 6379 }));
    }

    // Authenticate Socket.io using Cookie Auth
    sio.use(function(socket, next) {
        var handshake = socket.handshake;

        if (handshake.headers.cookie) {
            var req = {
                headers: {
                    cookie: handshake.headers.cookie
                }
            };

            cookieParser(config.sessionSecret)(req, null, function(err) {
                if (err) {
                    return next(err);
                }
                var sessionID = req.signedCookies['connect.sid'] || req.cookies['connect.sid'];
                sessionStore.get(sessionID, function (err, session) {
                    if (err) {
                        return next(err);
                    }

                    if (session) {
                        next();
                    } else {
                        return next(new Error('Invalid Session'));
                    }
                });
            });
        } else {
            next(new Error('Missing Cookies'));
        }
    });

// other express middleware set up
          // Handle Connection and disconnection
         sio.sockets.on('connection', function(socket) {
        console.log('user connected');
        socket.on('disconnect', function(){
            console.log('user disconnected');
        });
    });

    return server;

server.js (الملف بأكمله)

'use strict';
/**
 * Module dependencies.
 */
var init = require('./config/init')(),
    config = require('./config/config'),
    mongoose = require('mongoose'),
    cluster = require('cluster'),
    _ = require('lodash');


// Bootstrap db connection
var db = mongoose.connect(config.db);

// Init the express application
var server = require('./config/express')(db);

// Bootstrap passport config
require('./config/passport')();

// Start server.
var numCPUs = Math.ceil(require('os').cpus().length / 2);
if (cluster.isMaster) {
    var workers = [];

    // Helper function for spawning worker at index 'i'.
    var spawn = function(i) {
        workers[i] = cluster.fork();
        console.log('worker ' + workers[i].process.pid + ' created');

        // Optional: Restart worker on exit
        // workers[i].on('exit', function(worker, code, signal) {
        //  console.log('respawning worker', i);
        //  spawn(i);
        // });

        cluster.on('exit', function(worker, code, signal) {
            console.log('worker ' + worker.process.pid + ' died');
        });
    };

    // Spawn workers.
    for (var i = 0; i < numCPUs; i++) {
        spawn(i);
    }
} else {
    server.listen(config.port, function () {
        console.log('server started on ' + config.port + ' port');
    });
}

index.html (أهم جزء هنا)

<script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io.connect({transports: ['websocket']});
    </script>

نحتاج إلى تحديد استخدام بروتوكول websocket فقط مع Heroku. لأن الاستقصاء xhr لا يعمل! لا أعرف لماذا بعد.

آمل أن أتمكن اليوم من اختبار الاتصال بين المتصفحات الفكر مقبس / ريديس. سوف أشارك نتيجة ذلك.

gonzalodiaz شكرا جزيلا لك! سأحاول ذلك الأسبوع المقبل وسأخبرك إذا كنت سأجد بعض الأخطاء أو التحسينات.

gonzalodiaz ، إنه يعمل بشكل مثالي. الشيء السيئ فقط هو أن المتصفحات القديمة لا تدعم مآخذ الويب http://caniuse.com/#feat = websockets.

شكرا مرة اخرى.

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

حدثت هذه المشكلة عندما يستخدم العميل نقل الاقتراع الطويل ، ويستخدم الخادم وضع الكتلة.

استخدام جلسة لزجة سيتم إصلاح هذه المشكلة.

nauu Heroku لا يدعم الجلسات اللاصقة.

The Heroku routing infrastructure does not support “sticky sessions”. 
Requests from clients will be distributed randomly to all dynos running your application.

https://devcenter.heroku.com/articles/java-faq

gonzalodiaz هل يمكن لـ Heroku تشغيل الكتلة والاستماع في منفذ مختلف؟

إذا كان بإمكانه فعل ذلك ، يمكنك استخدام nginx لعكس الطلب من العملاء. واستخدم وحدة الجلسة اللاصقة الخاصة بـ nginx.

nauu لا ، لا يدعم Heroku الاستماع إلى منفذ مختلف. يقوم Heroku بتعيين المنفذ في متغير env ويقوم بتوزيع الحمل داخليًا بين dynos. إنه ألم حقًا.

فيما يتعلق بهذا الخطأ في Heroku ، لا يوجد حل إذا كنت تريد استخدام شيء مثل الكتلة التي تدعم كل socket.io وليس فقط مآخذ الويب؟

شكرا!

يمكنك محاكاة heroku محليًا بهذه الطريقة:

1- npm تثبيت فورمان -g
2- صدى "web: node app.js"> Procfile
3- nf start -x 3000 web = 3

سيبدأ هذا 3 مثيلات لخادمك (app.js) على المنفذ 5001 و 5002 و 5003 ولكن يمكنك الوصول إليهم من خلال الوكيل العكسي على المنفذ 3000.

قم بتشغيل هذا وحاول إنشاء اتصال websocket وسترى نفس المشكلة كما في heroku. عقدة فورمان هي طريقة جيدة لمحاكاة بيئة heroku محليًا. من المهم أن تضع في اعتبارك أنه على الرغم من أنه يمكنك الوصول إلى كل مثيل محلي مباشرةً ، إلا أنه لا يمكنك الوصول إلا إلى موازن التحميل على Heorku (المنفذ 3000 في المثال أعلاه)

ما هو الحل الجيد؟

@ ceram1 هل تحل المشكلة حتى الآن؟

+1

gonzalodiaz شكرًا لك على ذكر transports: ['websocket']

بالنسبة لأولئك الذين يواجهون هذه المشكلة خلف Amazon ELB ، تأكد من تمكين ثبات الجلسة التي يتحكم فيها التطبيق (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-sticky-sessions.html). هذا حل المشكلة بالنسبة لي.

يقرأ الرجال هذا المقال https://devcenter.heroku.com/articles/node-websockets
في النهاية ستجد أن التطبيقات التي تستخدم Socket.io يجب أن تعمل على تمكين تقارب الجلسة
ثم انتقل إلى https://devcenter.heroku.com/articles/session-affinity
ثم ضع Heroku Toolbelt CLI heroku features:enable http-session-affinity --app APP
وأنا سعيد بالعمل على socket.io على أجهزة ديناميكية متدرجة.

بالنسبة لي ، كان ذلك مع nginx ssl http2 ، وكان الاستقصاء ، لذا فإن التكوين الجيد هو:

 const ioSocket = io('', {
      // Send auth token on connection, you will need to DI the Auth service above
      // 'query': 'token=' + Auth.getToken()
      path: '/socket.io',
      transports: ['websocket'],
      secure: true,
    });

@ p3x-robot لقد تم إصلاحي بهذه الطريقة

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات