Node.js: socket.io close client connection - javascript

How can I close the socket connection on the client side?
I am using:
socket.io 0.9
node.js 0.10.15
express 3.3.4
i.e.:
call localhost/test
-- server side
var test = io
.of('/test')
.on('connection', function (socket) {
console.log('open socket: ' + socket);
socket.on('disconnect', function () {
console.log('disconnected event');
//socket.manager.onClientDisconnect(socket.id); --> endless loop with this disconnect event on server side
//socket.disconnect(); --> same here
});
});
-- client side
var socket = io.connect('http://localhost:3000/test');
socket.on('disconnect', function () {
console.log('disconnect client event....');
});
socket.emit('getInitData', function (data) {
.. do something with data
});
If I load the test-page I need some values from the server (getInitData).
On the first page visit I get the data once, on a reload or second visit I get it twice and so on.
The connection on the server side is beeing closed automatically on page reload and if you leave the page.
But on the client side the connection is still open.
How can I close the connection on the client side or check if there is already a open connection?
UPDATE
I tried now the following: (client side)
window.onbeforeunload = function(e) {
socket.disconnect();
};
This triggers on the client side the disconnect event, but I still get the twice or tripple response.

Did you try:
socket.disconnect()
on client?

For socket.io version 1.4.5:
On server:
socket.on('end', function (){
socket.disconnect(0);
});
On client:
var socket = io();
socket.emit('end');

There is no such thing as connection on server side and/or browser side. There is only one connection. If one of the sides closes it, then it is closed (and you cannot push data to a connection that is closed obviously).
Now a browser closes the connection when you leave the page (it does not depend on the library/language/OS you are using on the sever-side). This is at least true for WebSockets (it might not be true for long polling because of keep-alive but hopefuly socket.io handles this correctly).
If a problem like this happens, then I'm pretty sure that there's a bug in your own code (on the server side). Possibly you are stacking some event handlers where you should not.

socket.disconnect()
Only reboots the connection firing disconnect event on client side. But gets connected again.
socket.close()
Disconnect the connection from client. The client will keep trying to connect.

socket.disconnect() is a synonym to socket.close() which disconnect the socket manually.
When you type in client side :
const socket = io('http://localhost');
this will open a connection with autoConnect: true , so the lib will try to reconnect again when you disconnect the socket from server, to disable the autoConnection:
const socket = io('http://localhost', {autoConnect: false});
socket.open();// synonym to socket.connect()
And if you want you can manually reconnect:
socket.on('disconnect', () => {
socket.open();
});

I'm trying to close users connection in version 1.0 and found this method:
socket.conn.close()
The difference between this method and disconnect() is that the client will keep trying to reconnect to the server.

try this to close the connection:
socket.close();
and if you want to open it again:
socket.connect();

Just try socket.disconnect(true) on the server side by emitting any event from the client side.

Related

NodeJS Websocket client stay in pending mode

i have a simple js script that "try" to connect to listening server (SocketTest) as shown in the image below. It's really simple, just one line :
var exampleSocket = new WebSocket('ws://127.0.0.1:6601');
So, yes, it is connected but it stay in pending mode finishing by "failed: WebSocket opening handshake timed out"
Maybe i'm wrong somewhere but i don't see it... and it's really simple.
If someone got an idea....
Thanks in advance.
Without implementing open event do not expect any answer from the server :)
Try this:
const WebSocket = require('ws');
const ws = new WebSocket('ws://127.0.0.1:6601');
ws.on('open', function open() {
ws.send('something');
});
Edit: The nodejs tag fooled me I thought it is server side.
The same true on client side, you need to handle onopen event:
// Connection opened
exampleSocket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
exampleSocket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});

server can't run events on socket that reconected (Socket.io)

I'm a starter developer. I use socket.io for my app, which is based on a chat app.
I have a problem when the client disconnects accidentally (E.g. wi-fi on the PC disconnects). When wi-fi is connected again, the client enters the 'reconnect' event. After that, the connection is correctly reseted in the upper way (client to server) but won't work in the down way (server to client). After the re-connect my client will emit events that run on the server... but the server can't emit events that work on the client (the one that reconnected).
E.G:
client side:
I have this button created when the user logs in that when clicked sends the 'ready' event to the server.
socket.on('login', function (data) {
connected = true;
$matchId=data.id
var btn;
btn = document.createElement("BUTTON");
btn.innerHTML= "Ready";
btn.className = "readybtn";
btn.id = "readyBtn";
btn.onclick = function ready(){
socket.emit('ready',{
id: $matchId
});
};
document.getElementById("dropdownDiv").appendChild(btn);
});
server side (extract of one of the multiple events i've designed).
io.on('connection', function (socket) {
socket.on('ready', function(data){
var matchIdx;
for (var i = 0; i < srv.matches.length; i++) {
if(srv.matches[i].matchId == data.id) matchIdx = i;//indexOf
}
socket.to(srv.matches[matchIdx].matchId).emit('new message',{
username:socket.username,
message: "I'm ready"
});
}
});
Therefore, as you can see the when some client clicks on the Ready button, a I'm ready message with the client's username appears to everybody in the room.
My problem comes here, after the reconnect event (from socket.io) if I test this, the message will be displayed on all the clients except for those that reconnected. Even if I switch off the wi-fi on a client and then click on the ready button, I will see the I'm Ready message in all the clients but the one that reconnected. This means, that after the reconnect, the client is able to trigger the 'ready' event of the server, but the server cannot establish the connection to the client, since the 'new message' event is not triggered in the reconnected client.
I've tried to emit directly to the client that reconnected, to check if it is related to the rooms, but it does not work either.
Can somebody tell me how to solve this? Refreshing is not an option..
Thanks in advance.
I attach the reconnect event:
socket.on('reconnect', function () {
log("you were reconnected");
});
PS: Sorry for poor English and explanation, it is my first question.

Why does my socket.io app disconnect immediately when run on Raspberry pi?

I am attempting to build a node.js application on a Raspberry Pi which can communicate with a remote socket.io server.
The socket.io server quite simply writes to the console when a new connection is established and when an existing connection is closed.
The socket.io client works as expected when run in a browser.
However, when I run the client code from a Raspberry Pi it connects and immediately terminates. This does not allow me to perform any function such as emitting or receiving.
The on connect event is never fired.
var io = require('/usr/local/lib/node_modules/socket.io-client');
var serverUrl = 'http://remoteserver.com';
console.log('Connecting to ' + serverUrl);
var socket = io.connect(serverUrl);
socket.on('connect', function(socket) {
console.log('Connection established!');
console.log(socket.id);
socket.on('disconnect', function() {
console.log('Disconnected from server');
});
});
The code above will output:
Connecting to: http://remoteserver.com
On the server side, the output will show a new connection and eventually a timeout close.
Why is the client on connect event not firing? How can I persist this connection so that I can eventually send inputs to the server?
Remove the line:
socket.close();
from your code. You are closing the socket immediately. Remember that all the event handlers are asynchronous. They are non-blocking and will be called some time in the future. Meanwhile, the rest of your code runs to completion and thus your socket.close() is executed before your client has any chance to get any events (other than the disconnect event).
If you want to do some stuff and then close the socket, then you need to close the socket only from some event handler that indicates that your operation is complete and you are now done with the socket.
You only need to call socket.close() when you want to close the connection from the raspberry pi. Also, the socket.io-client documentation does not use the .connect method, but instead calls require('socket.io-client')(serverUrl)
var io = require('/usr/local/lib/node_modules/socket.io-client');
var serverUrl = 'http://remoteserver.com';
console.log('Connecting to ' + serverUrl);
var socket = io(serverUrl);
socket.on('connect', function(socket) {
console.log('Connection established!');
console.log(socket.id);
});
socket.on('disconnect', function() {
console.log('Disconnected from server');
});
//Removed the socket.close() line

get tab's socket instance on server

I have to get socket instance in my ajax request on server in node.js module. Here is my code.
app.js
io.set('authorization', function (handshake, callback) {
if (handshake.headers.cookie) {
cookieParser(handshake, null, function(err) {
handshake.sessionID = handshake.signedCookies['express.sid'];
});
} else { return callback('No cookie transmitted.', false); }
});
io.sockets.on('connection', function(socket) {
var session = socket.handshake.session;
var userid = session.userid;
socket.join("room");
//make user offline
socket.on('disconnect', function() {
//my code goes here...
//make user offline
})
});
Now in one of my ajax request, I want socket instance
app.post('/logout', function (req, res) {
//here i want socket instance, so I can emit message to all socket, accept this.
});
As I know, each tab creates it's own new socket connection, but session is unique between all tabs of browser. So, How Do I store socket for each tab on server side, where I can find easily socket instance, and then broadcast message to all sockets, excluding that socket which is creating events. (means user's active tab's socket connection)
any guess.
thanks
In my app, I can do what you say because i use namespace and room and so in a room i can find every socket of someone.
io.of('/user').clients(idRoom);
So that i can remove every socket of the user. But if you cannot use this, i think in your app you will have to implement outside socket.io a class for someone (using session as a way to see if it's already have a socket open or if you have to create a new instance). And in this class, have a socket table so that you will be able to handle socket of someone.
In my case, i do the same except that i use the room of socket.io to do that.
And to broadcast to every socket, it depends what is your app. If your app send to anyone in the same namespace, it doesn't change anything because the socket of the same session will also receive the message. But if not, you will have to implement a function to emit to every socket of the table i suggested above.
In my case i use the 'exclude' to ensure the current socket doesn't receive the message but usually you can use broadcast.
io.of('/user').in(this.id).except(socket.id).emit('msg', { text: text,type:person});
To conclude, socket.io will not help you to handle session and several socket for one user/session but you can manage to deal with it using room feature (in my case it was the best way), or implement a user class where you will manage a table of your session sockets.

Socket.io takes a long time before triggering the disconnect event

I'm doing an HTML5 Game using node.js and socket.io
I decided to host it on Heroku.
Heroku isn't allowing the use of WebSockets, so I have to setup xhr-polling instead. (Socket-io on Heroku)
io.configure( function() {
io.set( "transports", ["xhr-polling"] );
io.set( "polling duration", 10 );
} );
Before, I was using web-sockets only
io.set( "transports", ["websocket"] );
Now, when a client disconnect (close his window or refresh his page) the event "disconnect" isn't trigger immediatly on the server (it looks like it's waiting for the client heartbeat to time out).
client.on( "disconnect", onClientDisconnect );
If the client reloads, I get multiple connection events before disconnect is fired.
My problem is here.
Do you have any ideas, why xhr-polling doesn't fire the disconnect event ?
Is this a bad configuration of socket.io ?
Thanks.
It says here that you can configure the heartbeat. To properly configure it, you must adjust the heartbeat both on the server and the client side (which is given here).
Try lowering the heartbeat. It may solve your problem.
On other note, appfog seems to support websockets.
Just configure session auth and you can always know what client has connected. E.g.
io.set('authorization', function(handshakeData, ack) {
var cookies = require(...);
var signedCookies = parseCookies(cookies, secret);
sessionStore.get(signedCookies['connect.sid'], function(err, sessionData) {
handshakeData.session = sessionData || {};
handshakeData.sid = signedCookies['connect.sid'] || null;
ack(err, err ? false : true);
});
});

Categories

Resources