3

So I wanted to build a little game app with socket.io, it works like that:

User loads a website and I create a general socket using generalConnection namespace

app.generalSocket = io.connect('http://localhost/generalConnection'); 

I don't have any special events on it yet, but I thought it would be nice to keep it separate from a second namespace.

When the user logs in I call a function that starts game connection (another namespace) and bind some events to it, I won't list them all, I think it's not important.

app.startGameSocket = function() { app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection app.gameSocket.on("connect", function() { console.log("connected to the game socket"); }); } 

On the server side I have something like that:

var connectedPlayers = []; var gameConnection = io.of('/gameConnection').on('connection', function (socket) { socket.on('disconnect', function () { //some stuff }); }); 

Once again, I don't think I need to list all the events, I'll just explain how it works.

It listens to new player event, creates new player, pushes it connectedPlayers array and then sends it to everybody who is connected to gameConnection namespace.

User list is updated and everybody's happy. I can also listen to other events like disconnect and update the connectedPlayers array appropriately when user closes the browser window.

I also had to disconnect the gameConnection namespace when users log outs from the game, so on the client side I do:

app.vent.on('logOut', function() { app.gameSocket.disconnect(); )}; 

Notice that I keep generalConnection namespace open, I just disconnect the gameConnection namespace.

It works nice, if user logouts or closes window, disconnect event is triggered on the server side, connectedPlayers array is updated and sent back to connected players.

The problem

When user:

  1. Enters website.
  2. Logs in to the game.
  3. Logs out.
  4. Logs in again without refreshing window (triggers app.startGameSocket function again).
  5. And after all that closes the window, the gameConnection namespace disconnect event is not triggered on the server and list is not updated.

Node shell says stuff like: info - transport end (socket end) but not triggers the disconnect event. Please help :)

I tried to

app.vent.on('logOut', function() { app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side app.gameSocket.disconnect(); app.gameSocket.removeAllListeners(); //tried to really kill disconnected socket )}; 

But no results.

1
  • I've just found out that I can solve it by binding app.gameSocket.disconnect(); to the window.onbeforeunload event. So connection is killed when windows is closed, but I would love to understand whats wrong anyway Commented Mar 2, 2014 at 1:39

3 Answers 3

1

You can configure socket.io to disconnect the connection on window unload.

See the sync disconnect on unload option of the client in the Socket.io wiki. This option defaults to false, so it should solve your problem if you enable it.

app.gameSocket = io.connect('http://localhost/gameConnection', {'sync disconnect on unload':true}); //game connection 
Sign up to request clarification or add additional context in comments.

1 Comment

I've done something similar with window.onbeforeunload but neither my or your solution fixed it completly. I've answered my question with some details if you'd like to find out more.
1

Socket.io is not so much fun!

In my app each log out > log in process was

app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection 

So calling it multiple times like that was causing problems. I've changed it to something like this:

app.firstConnect = true; app.startGameSocket = function(){ if(app.firstConnect){ app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection }else{ app.gameSocket.socket.reconnect(); } } app.vent.on('logOut', function(){ app.firstConnect = false; }); 

My issues are gone, but socket.reconnect introduces another! You can read about it here https://github.com/LearnBoost/socket.io/issues/430

Comments

1

How socket identifies various client connected to it is, via socket parameter while connection. Then all other other event gets assigned to each socket-client under io.connection block as socket.on. Whenever any client gets connected or disconnected its own socket event(socket.on) gets called and socket.io identifies it with that socket paramenter and id of each socket.

Sample

io.sockets.on('connection', function(socket //unique client socket as parameter) { //code block } 

Eg:

io.sockets.on('connection', function(socket) { //connect Me(socket) socket.on('connect', function() { console.log('disconnected') }) //disconnect Me(socket) socket.on('disconnect', function() { console.log('disconnected') }) }); 

What your code doing is

app.vent.on('logOut', function() { app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side app.gameSocket.disconnect(); app.gameSocket.removeAllListeners(); //tried to really kill disconnected socket )}; 

its not emitting disconnect event of client specific socket

app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side 

Force disconnect but disconnect whom?

You need something like this

app.startGameSocket = function() { app.gameSocket = io.connect('http://localhost/gameConnection'); //game connection app.gameSocket.on("connect", function() { console.log("connected to the game socket"); }); //disconnect app.gameSocket.on("disconnect", function() { console.log("disconnected"); //force disconnect/logout code }); app.gameSocket.on('logOut', function() { //force disconnect/logout code app.gameSocket.emit('forceDisconnect'); //force disconnect on the server side app.gameSocket.disconnect(); app.gameSocket.removeAllListeners(); //tried to really kill disconnected socket )}; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.