3

I have an asynchronous funcion (closing a socket) that I have to execute when the user leaves the page. I've tried to do it through jQuery :

$(window).unload(function() {
   socket.disconnect();
});

However, this doesn't work because the function is asynchronous and the client leaves the page as soon as it reach the end of the method, that's to say instantly and the request to disconnect the socket is not performed.

We can provide a callback executed at the end of the socket.disconnect() function execution. Maybe this could help...

Is there a way in javascript to solve this ?

Cydonia7
  • 3,744
  • 2
  • 23
  • 32
  • 1
    Tricky. Couldn't you detect the departure on the server side and close it from there? – Mitya Jul 31 '12 at 09:02
  • Already tried it, I use Node.JS and it is detected 2 minutes after the client leaves. That's why I want to try "the client way", to be more effective. What's more, Node sometimes detects false disconnections so this may be the only right way to really detect one. – Cydonia7 Jul 31 '12 at 09:04
  • 1
    Is this `socket.io`? FYI, usually this problem is solved by using some kind of heartbeat to detect connection close from the server side. – igorw Jul 31 '12 at 09:08
  • 1
    @igorw Right but this detects it really late compared to the time when the clients really disconnect. – Cydonia7 Jul 31 '12 at 09:09
  • Not sure how Socket.IO works but that seems pointless, the socket should disconnect on page change, the connection is no longer open. I wrote my own WebSocket server so I had the ability to do this. – Sphvn Jul 31 '12 at 09:18
  • That seems to be a bug in fact. How did you handle this with your server ? – Cydonia7 Jul 31 '12 at 09:20

5 Answers5

3

I'm going to stick my neck out and say that I don't believe this is viable - at least not cross-browser.

As one suggested, you can interrupt navigation via onbeforeunload but this is not implemented the same cross-browser, and even if you can interrupt it, you can't (I believe) capture where the user was going, such that, in your socket closure callback, you could then forward them on.

An unideal compromise might be to use onbeforeunload to at least prompt them to manually disconnect from the server. Many will; those that don't you can pick up with server-side detection.

Mitya
  • 33,629
  • 9
  • 60
  • 107
  • I do like the idea, that's better than nothing, but that still requires a user action and we can't assume that everybody will do it. – Cydonia7 Jul 31 '12 at 09:14
  • I agree, I'm just saying you may not have much other choice. This is a limitation of your situation, not so much my answer :) – Mitya Jul 31 '12 at 09:15
  • You're right, I'll keep this as a solution if I can't find anything better. Thank you for your help ! – Cydonia7 Jul 31 '12 at 09:17
1
window.onbeforeunload = function () {
    socket.disconnect();
    return 'This will disconnect all connections'; //Throws a prompt to user
};

UPDATE: I hadn't seen that this won't work.

Is there any way to force this to synchronous?

Probably..

var complete = false;

socket.on('disconnect', function () {
    complete = true;
});

while(!complete){
    //do nothing
}

In my case, I do..

$.ajax({
    async: false    
});

Which works fine with onbeforeunload.

Robin Maben
  • 22,194
  • 16
  • 64
  • 99
0

Maybe you could try using the "beforeunload" event instead of "unload", like there, but I don't think there is a way to delay the window closing by another way.

Community
  • 1
  • 1
Ricola3D
  • 2,402
  • 17
  • 16
0

It now works in my local version because I have downgraded to socket.io 0.9.4. It was a bug indeed. Now it doesn't work on my host (Heroku) that has version 0.9.4 too (I configured it).

I don't know what to do to solve this but yay, at least it works in local...

Cydonia7
  • 3,744
  • 2
  • 23
  • 32
0

Take a look at a similar question I had, it turns out there was a bug in socket.io from 0.9.5 to 0.9.9.

Here's a link to my question. Hope this helps.

Community
  • 1
  • 1
scanales
  • 602
  • 1
  • 7
  • 18