How to cleanly disconnect from a namespace in socket.io? - node.js

I have been trying to disconnect from a namespace or even from the main socket connection itself but have been failing. Below is my code
Server Side:
socket.on('userDisconnect', function () {
socket.disconnect();
console.log("User Disconnected");
});
Client Side:
// already connected to /world namespace
socket.emit('userDisconnect');
socket.disconnect();
socket = io.connect('http://something/india' );
I tried disconnecting from both client and serve side but it doesnt work. Can anyone point out the mistake.
This is what is been written to console by socket.io
info - booting client
debug - websocket writing 0::/world
User Disconnected
debug - client authorized for /india
debug - websocket writing 1::/india
/world is the namespace its trying to disconnect from and then its trying to connect to /india namespace.

This worked for me
broadcastSocket.packet({ type: 'disconnect' });
broadcastSocket.$emit('disconnect');
disconnectNamespace(broadcastSocket.name, broadcastSocket.socket);
function disconnectNamespace (name,socket) {
if (socket.namespaces[name]) {
var nsp = socket.of(name);
nsp.packet({ type: 'disconnect' });
nsp.$emit('disconnect');
delete socket.namespaces[name];
if (Object.keys(socket.namespaces).length === 0) {
socket.disconnect();
}
}
};

For socket.io v.1.3.2
Create with:
sio = io('ws://localhost:13000/device');
Delete with:
sio.disconnect();
delete sio.io.nsps[sio.nsp]; // sio.nsp = '/device'
delete sio;
This worked for me.

On the server
nsp.on('connection', (socket) => {
setTimeout(() => {
socket.disconnect(false)
}, 5000);
});
Disconnects this client. If the value of close is true, closes the underlying connection. Otherwise, it just disconnects the namespace. It's in the documentation https://socket.io/docs/server-api/

It doesn't look like you told the client to wait for disconnect before reconnecting.
// already connected to /world namespace
socket.emit('userDisconnect');
socket.on('disconnect', function () {
socket = io.connect('http://something/india');
// stuff with india socket
});

Use disconnect() method on the server or on the client (or both like your did in your example). When you first connect to the server, add 'forceNew':false to the client connect method, something like this:
var socket = io('http://localhost:3001', {'forceNew':false});

Related

nothing happens when i emit some value to socket server

I have an expressjs server code which listen to a socket port like what you see below.
websocket.on('connection', (socket) => {
console.log('A client just joined on', socket.id);
websocket.on('messageIM', (message) => {
console.log('msg:'+message)
});
});
my client side application is a react-native mobile project which contains a code like this:
constructor(props) {
super(props);
this.socket = SocketIOClient('http://192.168.140.51:3000/');
}
and i get client connect 'A client just joined on ***' log on server console, means the connection to the server is successfully . but when i emit some variable .... nothing will happens in server side!...
call()=>{
this.socket.emit('messageIM','Hi server')
}
means when i call above call() function nothing happens in server.
this are the codes i'v written in both client and server side please give some help if you have some experience with that .
Looks like you used the wrong variable to listen on. The connection event returns the socket which is what you want to use. Rename websocket.on('messageIM' to socket.on('messageIM'
websocket.on('connection', socket => {
console.log('A client just joined on', socket.id);
socket.on('messageIM', message => {
console.log(`msg: ${message}`)
});
});

Create sockettimeoutexception with node js server

So I modified the accepted answer in this thread How do I shutdown a Node.js http(s) server immediately? and was able to close down my nodejs server.
// Create a new server on port 4000
var http = require('http');
var server = http.createServer(function (req, res) { res.end('Hello world!'); }).listen(4000);
// Maintain a hash of all connected sockets
var sockets = {}, nextSocketId = 0;
server.on('connection', function (socket) {
// Add a newly connected socket
var socketId = nextSocketId++;
sockets[socketId] = socket;
console.log('socket', socketId, 'opened');
// Remove the socket when it closes
socket.on('close', function () {
console.log('socket', socketId, 'closed');
delete sockets[socketId];
});
});
...
when (bw == 0) /*condition to trigger closing the server*/{
// Close the server
server.close(function () { console.log('Server closed!'); });
// Destroy all open sockets
for (var socketId in sockets) {
console.log('socket', socketId, 'destroyed');
sockets[socketId].destroy();
}
}
However, on the client side, the client throws a ConnectionException because of the server.close() statement. I want the client to throw a SocketTimeoutException, which means the server is active, but the socket just hangs. Someone else was able to do this with a jetty server from Java
Server jettyServer = new Server(4000);
...
when (bw == 0) {
server.getConnectors()[0].stop();
}
Is it possible to achieve something like that? I've been stuck on this for a while, any help is extremely appreciated. Thanks.
What you ask is impossible. A SocketTimeoutException is thrown when reading from a connection that hasn't terminated but hasn't delivered any data during the timeout period.
A connection closure does not cause it. It doesn't cause a ConnectionException either, as there is no such thing. It causes either an EOFException, a null return from readLine(), a -1 return from read(), or an IOException: connection reset if the close was abortive.
Your question doesn't make sense.

nodejs socket.io - connected to server but emit doesn't do anything

I'm starting to work with Socket.io and my nodeJS API
I succeeded to get my user connected, and showed a message on my server.
But now, I'm trying to send data to my client -> then server -> then client again etc.
But when I use emit nothing appends... So this i my code :
SERVER SIDE
io.on('connection', function(socket){
console.log("user connected") // I see that
socket.emit('text', 'it works!'); //
socket.on('test1', function (data) {
console.log('received 1 : '); // Never showed
console.log(data); // Never showed
});
}
CLIENT SIDE
var socket = io.connect(myUrl); // good connection
socket.emit ('test1', {map: 4, coords: '0.0'}); // never showed on the server side
socket.on('text', function(text) {
alert(text); // never showed
socket.emit('test', { "test": "test2" });
});
Any ideas?
thanks !
Your Starter Code seems to be valid, you need to check two things :
if you successfully included the socket.min.js in the client side
if you re having any error printed in the console
On the client side, you have to wait until the connection succeeds before it is safe to send data to the server. Connecting to the server is not synchronous or instantaneous (thus it is not ready immediately). You are trying to send data before the connection is ready.
Put your first send of data inside a socket.on('connect', ...) handler.
var socket = io.connect(myUrl); // good connection
// send some data as soon as we are connected
socket.on('connect', function() {
socket.emit ('test1', {map: 4, coords: '0.0'});
});
socket.on('text', function(text) {
alert(text); // never showed
socket.emit('test', { "test": "test2" });
});
this worked for me
CLIENT SIDE
//sending custom data to server after successful connection
socket.on('connect', function(){
this.socket.emit('client-to-server', {map: 4, coords: '0.0'});
});
//listening the event fired by the socket server
socket.on('server-to-client', function(dataSendbyTheServer){
// do whatever you want
console.log(dataSendbyTheServer);
});
SERVER SIDE
io.on('connection', function(socket) {
// listening the event fired by the client
socket.on('client-to-server', function (data) {
console.log('received 1 : ');
// sending back to client
io.emit('server-to-client', data)
});
});

Prevent Socket connection from initializing again

I am trying to make a chat app which sends first message as "Hi. there".
But due to some some reasons (unstable internet connection might be one) the socket get initialized multiple times and sends the "Hi. there" message multiple times. Below is the code. How to stop the app for sending multiple messages?
io.socket.on('connect', function() {
/* On successfull connection to server */
console.log('Connected to server');
//Some code here
io.socket.get(url + '/userstatus/subscribe', function(resData, jwres) {
//Some code here
io.socket.on("userstatus", function(event) {
//Socket updartes
// Send Message code at this line.
}
}
});
You need to change your client side code, so that it stores state, and sends it to the server on reconnect. That way the server can give the correct response.
Something like this might work:
socket.on('connect', function() {
/* On successfull connection to server */
console.log('Connected to server');
socket.emit('state', state_object);
});

Node.js and Socket.IO - How to reconnect as soon as disconnect happens

I'm building a small prototype with node.js and socket.io. Everything is working well, the only issue I'm facing is that my node.js connection will disconnect and I'm forced to refresh the page in order to get the connection up and running again.
Is there a way to reestablish the connection as soon as the disconnect event is fired?
From what I've heard, this is a common issue. So, I'm looking for a best-practice approach to solving this problem :)
Thanks very much,
Dan
EDIT: socket.io now has built-in reconnection support. Use that.
e.g. (these are the defaults):
io.connect('http://localhost', {
'reconnection': true,
'reconnectionDelay': 500,
'reconnectionAttempts': 10
});
This is what I did:
socket.on('disconnect', function () {
console.log('reconnecting...')
socket.connect()
})
socket.on('connect_failed', function () {
console.log('connection failed. reconnecting...')
socket.connect()
})
It seems to work pretty well, though I've only tested it on the websocket transport.
edit: Socket.io has builtin-support now
When I used socket.io the disconnect did not happen(only when i closed the server manually). But you could just reconnect after say for example 10 seconds on failure or something on disconnect event.
socket.on('disconnect', function(){
// reconnect
});
I came up with the following implementation:
client-side javascript
var connected = false;
const RETRY_INTERVAL = 10000;
var timeout;
socket.on('connect', function() {
connected = true;
clearTimeout(timeout);
socket.send({'subscribe': 'schaftenaar'});
content.html("<b>Connected to server.</b>");
});
socket.on('disconnect', function() {
connected = false;
console.log('disconnected');
content.html("<b>Disconnected! Trying to automatically to reconnect in " +
RETRY_INTERVAL/1000 + " seconds.</b>");
retryConnectOnFailure(RETRY_INTERVAL);
});
var retryConnectOnFailure = function(retryInMilliseconds) {
setTimeout(function() {
if (!connected) {
$.get('/ping', function(data) {
connected = true;
window.location.href = unescape(window.location.pathname);
});
retryConnectOnFailure(retryInMilliseconds);
}
}, retryInMilliseconds);
}
// start connection
socket.connect();
retryConnectOnFailure(RETRY_INTERVAL);
serverside(node.js):
// express route to ping server.
app.get('/ping', function(req, res) {
res.send('pong');
});
Start reconnecting even if the first attempt fails
If the first connection attempt fails, socket.io 0.9.16 doesn't try to reconnect for some reason. This is how I worked around that.
//if this fails, socket.io gives up
var socket = io.connect();
//tell socket.io to never give up :)
socket.on('error', function(){
socket.socket.reconnect();
});
I know this has an accepted answer, but I searched forever to find what I was looking for and thought this may help out others.
If you want to let your client attempt to reconnect for infinity (I needed this for a project where few clients would be connected, but I needed them to always reconnect if I took the server down).
var max_socket_reconnects = 6;
var socket = io.connect('http://foo.bar',{
'max reconnection attempts' : max_socket_reconnects
});
socket.on("reconnecting", function(delay, attempt) {
if (attempt === max_socket_reconnects) {
setTimeout(function(){ socket.socket.reconnect(); }, 5000);
return console.log("Failed to reconnect. Lets try that again in 5 seconds.");
}
});

Resources