змусити клієнт відключитися від сервера за допомогою socket.io та nodejs


117

Чи є спосіб відключити клієнта з SocketIO і буквально закрити з'єднання? Отже, якщо хтось підключений до мого сервера, і я хочу перервати зв'язок між ними та моїм сервером, то як би мені це зробити?

Відповіді:


146

Редагувати: це зараз можливо

Тепер ви можете просто зателефонувати socket.disconnect()на сторону сервера .

Моя оригінальна відповідь:

Це ще неможливо.

Якщо вам це теж потрібно, проголосуйте / прокоментуйте це питання .


Тому я це роблю, і це змушує клієнта відключитися, але, на жаль, виявляється, що клієнт просто знову підключається. Я нерозумію, що відбувається, чи це очікувана поведінка?
— kybernetikos

@kybernetikos Так, я б очікував цього - клієнт може все-таки вибрати, що робити зі своїми. Часто вам хочеться виштовхнути іншу сторону від поточного з'єднання, скажімо, через автентичний тайм-аут - повторне підключення після цього, ймовірно, навіть бажано.
— nh2

Тож чи знаєте ви про будь-який спосіб сказати клієнтові «йди, і я це справді маю на увазі»? Я думаю з точки зору того, щоб визначити, що клієнт веде себе погано і не хоче, щоб він використовував ресурс на моєму сервері.
— kybernetikos

@kybernetikos Ні, ви не можете цього зробити (як правило). Якщо ви програмуєте клієнтську сторону, ви, звичайно, можете реалізувати будь-яку потрібну вам логіку, наприклад, припинити її повторне підключення. Якщо ні, доведеться неодноразово бити користувачів або, якщо це дійсно необхідно, вдаватися до стандартних методів блокування; чим нижчий рівень їх реалізовано (наприклад iptables), тим більше ресурсів ви заощадите. У більшості випадків просто натискання на клієнта повинно бути достатнім, оскільки socketio не з'єднує це так швидко, і якщо хтось дійсно хоче зробити вам DoS, у нього все одно є інші способи (наприклад, завантажувати з вас сторінки).
— nh2

1
@ManishSapkal Ви, напевно, повинні відкрити нове запитання для цього, воно не вписується добре в коментарі.
— nh2

15

socket.disconnect() може використовуватися лише на стороні клієнта, а не на стороні сервера.

Client.emit('disconnect')запускає подію відключення на сервері, але не ефективно відключає клієнта. Клієнт не знає про відключення.

Тож залишається питання: як змусити клієнта відключитися від серверної сторони?


1
Вам більше не доведеться дзвонити Client.emit('disconnect')вручну з останніми версіями socket.io, тепер є сервер socket.disconnect()(див. Мою відповідь).
— nh2

5
Через останні оновлення ваш амсевер зараз неправильний, отже -1.
— corazza

Я погоджуюся, ця відповідь більше не є дійсною, тому що тепер її socket.disconnect()можна використовувати і на стороні сервера.
— Vassilis Barzokas

@VassilisBarzokas Що робити, якщо я хочу зворотний дзвінок і передати деякі параметри зворотному дзвінку після завершення disconnect()функції?
— newguy

створіть узгоджений набір повідомлень, коли одна сторона повідомляє іншу сторону, що бажає відключитися, потім зробіть те, що вам потрібно зробити, а потім фактично відключіться.
— Майк 'Помакс' Камерманс

8

Будь-яка причина, через яку сервер не може надсилати повідомлення клієнту, через який він викликає функцію відключення?

Про клієнта:

socket.emit('forceDisconnect');

На сервері:

socket.on('forceDisconnect', function(){
    socket.disconnect();
});

7
Тому що ніколи не можна покластися на код клієнта, щоб він працював так, як вам хочеться. Користувачі можуть легко модифікувати його.
— Kaustubh Karkare

4

Припустимо, що названий гніздо вашого сокета, використовуйте:

socket.disconnect()

2
На жаль, це не працює. Я намагаюся закрити з'єднання з певним клієнтом з боку сервера.
— Даніель Кенні

4

Для тих, хто знайшов це в google - зараз є рішення для цього:

Socket.disconnect()натискає на клієнта (на стороні сервера). Немає шансів для клієнта залишатися на зв'язку :)


Як знайти сокет користувача, відключеного на сервері?
— Manish Sapkal

Manish: Прослухайте disconnectподію сокету, щоб з’ясувати, чи не відключився він. Може також бути closeподією, я не зовсім впевнений. Для отримання додаткової інформації про це див. Документацію на socket.io.
— Саша Геліх


3

У моєму випадку я хотів зірвати базове з'єднання, і в такому випадку мені довелося зателефонувати, socket.disconnect(true)як ви бачите, потрібне з джерела тут


2

client._onDisconnect() повинен працювати


1
Це прекрасно працює. Я підтримую власне картографування для клієнтів .. використовуючи це картографування ... легко відключаючи клієнтів .. ура
— Arenstar

1

Socket.io використовує шаблон EventEmitter для відключення / підключення / перевірки серцебиття, щоб ви могли це зробити. Client.emit('disconnect');


1

Це не спрацювало для мене:

`socket.disconnect()` 

Це спрацювало для мене:

socket.disconnect(true)

Передача trueзакриє нижнє з'єднання з клієнтом, а не лише простір імен, до яких підключений клієнт до документації Socket IO .


Приклад використання випадку: Клієнт підключився до сервера веб-сокет з недійсним маркером доступу (маркер доступу, переданий на сервер веб-сокет з парамами з'єднання). Сервер веб-сокетів повідомляє клієнта, що він перерве з'єднання через його недійсний маркер доступу:

// (1) the server code emits
socket.emit('invalidAccessToken', function(data) {
    console.log(data);       // (4) server receives 'invalidAccessTokenEmitReceived' from client
    socket.disconnect(true); // (5) force disconnect client 
});

// (2) the client code listens to event
// client.on('invalidAccessToken', (name, fn) => { 
//     // (3) the client ack emits to server
//     fn('invalidAccessTokenEmitReceived');
// });

0

Я використовую client.emit('disconnect')+ client.removeAllListeners()для підключеного клієнта для ігнорування всіх подій після відключення


0

Я використовую на стороні клієнта socket.disconnect();

client.emit('disconnect') didnt work for me

0

використання:

socket.Disconnect () // ок

не використовувати :

socket.disconnect ()


0

Ви можете socket = undefinedстерти, який сокет ви підключили. Тож коли потрібно підключити do socket (URL)

Так буде виглядати так

const socketClient = require('socket.io-client');

let socket;

// Connect to server
socket = socketClient(url)

// When want to disconnect
socket = undefined;

-1

Додайте нові масиви підключення до масиву, а потім, коли ви хочете закрити всі, - перевірте їх і від'єднайте. (серверна сторона)

var socketlist = [];

   io.sockets.on('connection', function (socket) {
        socketlist.push(socket);  
        //...other code for connection here..
   });


    //close remote sockets
    socketlist.forEach(function(socket) {        
        socket.disconnect();                      
    });    
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.