принудительно отключить клиента от сервера с помощью 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()можно использовать и на стороне сервера.
Василис Барзокас

@VassilisBarzokas Что, если мне нужен обратный вызов и передать некоторые параметры в обратный вызов после завершения disconnect()функции?
newguy

создайте согласованный набор сообщений, в котором одна сторона информирует другую сторону о своем желании отключиться, затем делает то, что вам нужно, а затем фактически отключается.
Mike 'Pomax' Kamermans

8

Есть ли причина, по которой сервер не может отправлять клиенту сообщение, которое заставляет его вызывать функцию отключения?

На клиенте:

socket.emit('forceDisconnect');

На сервере:

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

7
Потому что на клиентский код нельзя полагаться, чтобы он работал так, как вы хотите. Пользователи могут легко его изменить.
Kaustubh Karkare 08


4

Предполагая, что ваш сокет назван socket, используйте:

socket.disconnect()

2
К сожалению, это не работает. Я пытаюсь закрыть соединение с конкретным клиентом со стороны сервера.
Дэниел Кенни

4

Для тех, кто нашел это в гугле - прямо сейчас есть решение:

Socket.disconnect()пинает клиента (на стороне сервера). У клиента нет шансов оставаться на связи :)


Как найти сокет пользователя, который отключен от сервера?
Маниш Сапкал

Маниш: прослушайте disconnectсобытие сокета, чтобы узнать, отключился ли он. Тоже может быть closeсобытие, я не совсем уверен. См. Документацию socket.io для получения дополнительной информации об этом.
Sascha Gehlich

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стереть, какой сокет вы подключили. Итак, когда вы хотите подключиться, сделайте сокет (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.