force client disconnect from server with socket.io and nodejs - socket.io

Is there any way to disconnect a client with SocketIO, and literally close the connection? So if someone is connected to my server, and I want to close the connection between them and my server, how would I go about doing that?

Edit: This is now possible
You can now simply call socket.disconnect() on the server side.
My original answer:
This is not possible yet.
If you need it as well, vote/comment on this issue.

socket.disconnect() can be used only on the client side, not on the server side.
Client.emit('disconnect') triggers the disconnection event on the server, but does not effectively disconnect the client. The client is not aware of the disconnection.
So the question remain : how to force a client to disconnect from server side ?

Any reason why you can't have the server emit a message to the client that makes it call the disconnect function?
On client:
socket.emit('forceDisconnect');
On Server:
socket.on('forceDisconnect', function(){
socket.disconnect();
});

Checking this morning it appears it is now:
socket.close()
https://socket.io/docs/client-api/#socket-close

For those who found this on google - there is a solution for this right now:
Socket.disconnect() kicks the client (server-side). No chance for the client to stay connected :)

Assuming your socket's named socket, use:
socket.disconnect()

This didn't work for me:
`socket.disconnect()`
This did work for me:
socket.disconnect(true)
Handing over true will close the underlaying connection to the client and not just the namespace the client is connected to Socket IO Documentation.
An example use case: Client did connect to web socket server with invalid access token (access token handed over to web socket server with connection params). Web socket server notifies the client that it is going to close the connection, because of his invalid access token:
// (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');
// });

In my case I wanted to tear down the underlying connection in which case I had to call socket.disconnect(true) as you can see is needed from the source here

client._onDisconnect() should work

I'm using client.emit('disconnect') + client.removeAllListeners() for connected client for ignore all events after disconnect

Socket.io uses the EventEmitter pattern to disconnect/connect/check heartbeats so you could do. Client.emit('disconnect');

I am using on the client side socket.disconnect();
client.emit('disconnect') didnt work for me

You can do socket = undefined in erase which socket you have connected. So when want to connected do socket(url)
So it will look like this
const socketClient = require('socket.io-client');
let socket;
// Connect to server
socket = socketClient(url)
// When want to disconnect
socket = undefined;

I have using the socket client on React Native app, when I called socketIOClient.disconnect() this disconnects from the server but when I connect to the socket again the previous events were connected again, and the below code works for me by removing all existing events and disconnecting socket conneciton.
socketIOClient.removeAllListeners();
socketIOClient.disconnect(true);

To disconnect socket forcefully from server side
socket.disconnect(true)
OR
To disconnect socket by client side event
On client:
socket.emit('forceDisconnect');
On Server:
socket.on('forceDisconnect', function(){
socket.disconnect(true);
});

You can call socket.disconnect() on both the client and server.

Add new socket connections to an array and then when you want to close all - loop through them and disconnect. (server side)
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();
});

use :
socket.Disconnect() //ok
do not use :
socket.disconnect()

Related

connecting autobahn websocket server to crossbar.io router

I have an application that connects to a web page that sends and receives text strings over a websocket on port 1234. I do not have access to the front end code, so I cannot change the HTML front end code.
I created an autobahn server with a class derived from WebSocketServer protocol that communicates with the web page over port 1234. This works and I am able to send and receive text to the front end.
However, I need to process incoming data and would like to publish the received data to a crossbar.io container through the router on port 8080 (or any other port). The port to the web browser is fixed at 1234.
It there a way for me to "plug in " the autobahn websocket server into the crossbar router or is there an alternative way to create a websocket server that will allow me to to send and receive the text on port 1234 and at the same time participate in pub/sub and RPC with the crossbar router?
I am assuming you are using Python. If you are not, the answer should still be the same, but depending on the language/library and its implementation the answer can change.
From what you are saying, it does not sound like you really need a "plug in". Crossbar does have these under the description of router components. But unless you really need to attach a Python instance directly to the router either for performance or otherwise, I would recommend keeping your application off the router. It would work perfectly fine as a stand alone instance especially if it is on the same machine where the WAMP router is located where the packets would only require to communicate over loopback (which is VERY fast).
Given that you are using Python:
You can use your WebSocketServer and a WampApplicationServer together. The little hiccup you might run into is starting them up properly. In either scenario Python2.x with twisted or Python3.4 with Asyncio you can only start the reactor/event loop once or an error will ensue. (Both Twisted and Asyncio have the same basic concept) In Asyncio you will get RuntimeError: Event loop is running. if you attempt to start the event loop twice. Twisted has a similar error. Using the ApplicationRunner in twisted, there is an option (second argument in run) not to start up the reactor which you can use after the reactor is already running. In Asyncio, there is no such option, the only way I found out how to do it is to inherit the Application runner and overwrite the run method to start the session to be started as a task. Also, be warned that threads do not cooperate with either event loop unless properly wrapped.
Once you have the two connections set up in one instance you can do whatever you want with the data.
Thanks for the idea, and the problems you mention are exactly what I encountered. I did find a solution however, and thanks to the flexibility of crossbar, created a JavaScript guest that allows me to do exactly what I need. Here is the code:
// crossbar setup
var autobahn = require('autobahn');
var connection = new autobahn.Connection({
url: 'ws://127.0.0.1:8080/ws',
realm: 'realm1'
}
);
// Websocket to Scratch setup
// pull in the required node packages and assign variables for the entities
var WebSocketServer = require('websocket').server;
var http = require('http');
var ipPort = 1234; // ip port number for Scratch to use
// this connection is a crossbar connection
connection.onopen = function (session) {
// create an http server that will be used to contain a WebSocket server
var server = http.createServer(function (request, response) {
// We are not processing any HTTP, so this is an empty function. 'server' is a wrapper for the
// WebSocketServer we are going to create below.
});
// Create an IP listener using the http server
server.listen(ipPort, function () {
console.log('Webserver created and listening on port ' + ipPort);
});
// create the WebSocket Server and associate it with the httpServer
var wsServer = new WebSocketServer({
httpServer: server
});
// WebSocket server has been activated and a 'request' message has been received from client websocket
wsServer.on('request', function (request) {
// accept a connection request from Xi4S
//myconnection is the WS connection to Scratch
myconnection = request.accept(null, request.origin); // The server is now 'online'
// Process Xi4S messages
myconnection.on('message', function (message) {
console.log('message received: ' + message.utf8Data);
session.publish('com.serial.data', [message.utf8Data]);
// Process each message type received
myconnection.on('close', function (myconnection) {
console.log('Client closed connection');
boardReset();
});
});
});
};
connection.open();

How do I close a server with socket.io (stop it from listening to a port)

how can I close a listener that was opened with socket.io
something like this:
io = require('socket.io').listen(3333);
and then at some time:
io.closeListener()
On server side, you can do this:
socket.disconnect();
To disconnect every client (yeah you have to go one by one):
for (user in io.sockets.sockets) {
io.sockets.sockets[user].disconnect();
}
To close the server:
io.server.close();

socket.io not falling back to other methods when blocked behind firewall

I've got my client side socket config settings as
io.set('transports', [
'websocket',
'flashsocket',
'htmlfile',
'xhr-polling',
'jsonp-polling'
]);
When I am behind my corporate firewall, The client claims to connect to the server. But then when I try and send/receive message, it doesn't work. I need it to just fallback to another transport method, but, can't figure out how to configure it to do that.
How can I detect if I am behind a corporate firewall (and therefore not "truly" connected to socket even when I receive a connected response) and then fallback on another method?
Note that this prints "connected" out to the console behind the firewall, but then when I try and send/receive messages, it doesn't work:
app.iosocket.on('connect', function(){
console.log('connected');
});
Try to attach event listeners to the 'connection', 'connect' and 'error' events to inspect what going wrong.

How to determine transport type in sockio?

in socketIO , how to check the transport type (i.e. xhr-polling or websockets or flash sockets) on which client & server communicating ? (i'm using netty server with java)
thanks in advance :)
On the client side, you can use the variable socket.socket.transport.name. Server-side you can use the variable socket.transport or you can check the name of the transport by connection ID.
In your connection callback, the expression is io.transports[conn.id].name. As a simple test:
io.sockets.on('connection', function(conn) {
console.log(io.transports[conn.id].name);
});

Broadcasting in socket.io?

How to broadcast a message among all the connected clients in socket.io?
I am using mrniko/netty-cosket.io server with with java (play/eclipse) on server side and socket.io.js 0.9 on client side. Both client & server working fine (i.e. sending and receiving messages). To keep the records of the connected clients , I am using hashMaps and to send a message to all connected users I am iterating the hashmap and sending messages one by one. just wanna know is there any better way to send messages to all connected clients at once?
Any help will be highly appreciated.
Here is an example in case of mrniko/netty-socket.io usage:
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
SocketIOServer server = new SocketIOServer(config);
BroadcastOperations bo = server.getBroadcastOperations();
// every method will broadcast messages to all server clients
bo.sendJsonObject(...)
server.start();
...
you can use the following code:
//broadcasts to all clients connected
io.sockets.emit('function', {foo:bar});
//broadcasts to all clients connected, except the sender
io.sockets.on('connection', function (socket) {
socket.on('message', function(data) {
socket.broadcast.emit('function', {foo:bar});
}
}

Resources