Socket.io: لا ترسل البرامج الوسيطة (.use) الاتصال عند استخدام مساحة اسم مخصصة

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

اتريد:

  • [x] أبلغ عن خطأ
  • [] طلب ميزة

السلوك الحالي

عند استخدام مساحة اسم مخصصة مع برمجية وسيطة ، يحصل الخادم على حدث "اتصال" ، لكن العميل لا يتلقى حدث "اتصال".

هذا يعمل:

io.use((socket, next) => {
   console.log('middleware running...');
   next();
}).on('connection', socket => {
  console.log('client connected');
});

هذا لا يعمل:

// Following works, but client does not receive 'connect' or 'connection':
io.of('/admin').use((socket, next) => {
   console.log('middleware running...');
   next();
}).on('connection', socket => {
  console.log('client connected');
});

Sitenotes

غريب جدًا أيضًا: إذا قمت بتنفيذ الكود التالي ، فإن مساحة الاسم الافتراضية أيضًا لا تصدر أي حدث "اتصال" حتى مع عدم تشغيل البرنامج الوسيط من / admin.

io.on('connection', socket => {
  console.log('client connected');
});

io.of('/admin').use((socket, next) => {
   console.log('middleware running...');
   next();
}).on('connection', socket => {
  console.log('client connected');
});

لإصلاح ذلك ، يجب علي إضافة .use((socket, next) => { next(); }) إلى مساحة الاسم الافتراضية. ولكن لا يزال / المسؤول لا يرسل "اتصال".

خطوات إعادة الإنتاج (إذا كان السلوك الحالي خطأ)

من فضلك انظر أعلاه

سلوك متوقع

عند الاتصال ، يجب أن يتلقى العميل "اتصال"

اقامة

  • نظام التشغيل: macOS Sierra 10.12.6
  • المتصفح: كروم
  • العقدة: v8.2.1
  • NPM: 5.4.2
  • الإصدار socket.io: 2.0.3
bug

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

JanisRubens شكرًا على التقرير المفصل: +1: ، تمكنت في النهاية من التكاثر. تم الإصلاح بواسطة https://github.com/socketio/socket.io/pull/3197

ال 12 كومينتر

مرحبا! كيف تقوم بتهيئة العميل؟ يبدو أن ما يلي يعمل بالنسبة لي:

io.use((socket, next) => {
   console.log('(default) middleware running...');
   next();
}).on('connection', socket => {
  console.log('(default) client connected');
});

// Following works, but client does not receive 'connect' or 'connection':
io.of('/admin').use((socket, next) => {
   console.log('(admin) middleware running...');
   next();
}).on('connection', socket => {
  console.log('(admin) client connected');
});

// client
const socket = require('socket.io-client')('http://localhost:3000/admin');

socket.on('connect', onConnect);

function onConnect(){
  console.log('connect ' + socket.id);
}

الإخراج ( كمان ):

server listening on port 3000
(default) middleware running...
(default) client connected
(admin) middleware running...
(admin) client connected

لا انها لا تعمل بالنسبة لي. كود كامل ، مثال عملي:

الخادم:

let express = require('express'),
    app = new express(),
    server = app.listen(3005, 'localhost'),
    io = require('socket.io')(server)
;

io.on('connection', socket => {
  console.log('client connected');
});

io.of('/admin')
  .use((socket, next) => {
    console.log('middleware running...');
    next();
  })
  .on('connection', socket => {
    console.log('admin connected');
  })
;

عميل:

$(function () {
    let socket;

    $('#btn-connect').click(() => {
        console.log('Connecting ...');

        socket = io('http://localhost:3005');

        socket.on('connect', () => {
            console.log(`Connected to ${url} with id: ${socket.id}`);
        });

        socket.on('disconnect', reason => {
            console.log(`Disconnected. Reason: ${reason}`);
        });
    });

    $('#btn-connect-admin').click(() => {
        console.log('Connecting to admin ...');

        socket = io('http://localhost:3005/admin');

        socket.on('connect', () => {
            console.log(`Connected to ${url} with id: ${socket.id}`);
        });

        socket.on('disconnect', reason => {
            console.log(`Disconnected. Reason: ${reason}`);
        });
    });
});

إذا قمت بإزالة البرامج الوسيطة يمكنني الاتصال بكليهما. إذا قمت بإضافة البرامج الوسيطة للمسؤول فقط ، فلن أحصل على حدث اتصال في مساحة الاسم الافتراضية ولا / admin.

يظهر الخادم كل شيء بشكل صحيح:

  • العميل متصل
  • الوسيطة قيد التشغيل ...
  • المشرف متصل

لا شيئ؟ :(

MickL أي تحديثات على هذا؟
ركض في نفس المشكلة أيضًا.
لست متأكدا إذا كنت قد رصدت هذا. مشكلة الاتصال الوحيدة هي مع مساحة اسم الجذر ، وإذا أضفت برمجية وسيطة أيضًا لمسار الجذر ، فستتمكن من الاتصال بها أيضًا. (يمكن أن يكون هذا إصلاحًا سريعًا tbh)

يتعلق الأمر بالسيناريوهات التالية:

If namespace A('/)' and B('/otherPath') has no middleware it connects to both fine;
If namespace A has no middleware and B has. It connects to A on server side, but client sides 'connect' event listener never gets called, B namespace connects fine;
If namespace A and B both has middleware it can connect to both;

لا ، لقد استخدمت حلاً. بدلا من:

io.of('/admin')
  .use((socket, next) => {
    if(tokenValid()) {
       next();
    } else {
      next(new Error('Authentication error'));
    }
  })
  .on('connection', socket => {
    console.log('admin connected');
  })
;

كتبت:

io.of('/admin')
  .on('connection', socket => {
    if(!tokenValid()) {
       socket.disconnect();
    }

    console.log('admin connected');
  })
;

لقد أنفقت كثيرًا على هذا ويبدو أن العميل يتصل بالخادم ولكن العميل لا يحصل على حدث الاتصال.

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

darrachequesne المثال الذي قدمته واختبرت عليه لا

تحتاج إلى إزالة البرامج الوسيطة من مساحة الاسم الافتراضية ثم محاولة الاتصال.

مثله:

io.on('connection', socket => {
  console.log('(default) client connected');
});

io.of('/admin').use((socket, next) => {
   console.log('(admin) middleware running...');
   next();
}).on('connection', socket => {
  console.log('(admin) client connected');
});

// client
const socket = require('socket.io-client')('http://localhost:3000/');
const socket_two = require('socket.io-client')('http://localhost:3000/admin');
//wont trigger
socket.on('connect', onConnect);
//will trigger
socket_two.on('connect', onConnect);

function onConnect(){
  console.log('connect ' + socket.id);
}

الآن يجب أن تفشل.
انظر الحالات عندما يعمل / لا يعمل أعلاه.

في صحتك.

JanisRubens شكرًا على التقرير المفصل: +1: ، تمكنت في النهاية من التكاثر. تم الإصلاح بواسطة https://github.com/socketio/socket.io/pull/3197

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

+1

adeelhussainElioTohm الإصدار الذي تستخدمه؟ هل أنت قادر على إعادة إنتاج القضية بالكمان ؟

باستخدام socketio v2.1.1 و socket.io-redis v5.2.0
سأحاول إعادة إنتاجه باستخدام الكمان في أسرع وقت ممكن

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