Here's the scenario, I have a client side application, served by PHP on a different server to the node.js + socket.io application. It can connect and receive broadcasts sent from the server. If the connection drops, the application falls back to polling a database (using setInterval()). It attempts to reconnect every 5 polls, and it can successfully reconnect and continue to receive messages.
My problem occurs when the user loads the page and the node server cannot be reached (I turned it off for testing), I then turn on the server and on the 5th poll, it successfully connects to the server, using socket.socket.reconnect();. However, whenever the server broadcasts messages, it doesn't fire the event. Note that this doesn't happen when testing on a phone (which falls back to a different socket method)
I have already seen the question found here Reconnection in socket.io problem in `socket.on('message',function(){})`, however, the socket has not previously been connected so I don't think it could be the session?
EDIT: I changed the socket.socket.reconnect() to socket.socket.connect() and it fixed the problem. If someone could explain the reasons of why this works I'd like to know. I know its because the server isn't actually reconnecting, but would like more info.
Thanks.
well you possibly know the reason for this. server is not reconnecting. it is actually connecting. when you tell socket.io to reconnect it searches for the previous connection handle and thats where the problem arises.
Related
I am trying to get a handle on the various connection/disconnection events and how to use these to make sure that my application will always terminate gracefully.
I understand that socket.io will automatically attempt to reconnect a specified number of times. It is my understanding that as the connection goes down and subsequently reconnects there will be a disconnection event fired server side. I do not care about the connection temporarily going down so long as it comes back up at some point.
However if there is a more permanent disconnect, I do care about this and would need to update data such as connected users. I understand that on the client side you can get a reconnect_failed error object but I do not believe you can listen for this on the server. Is there any way to get notification on the server side that the connection is down and reconnection has failed? If so how does socket.io implement this?
I could issue a timeout upon a disconnection event server side that removes users if there is no reconnection. I could also have the server ping all connected clients at certain intervals. Are these kinds of solutions the only way to completely deal with all kinds of possible disconnections?
I am making a game where a node server speaks to javascript clients using socket.io. Players can connect and disconnect from the game and the server keeps track of who is connected. However, I have found that on many occasions when i close the server, close all open client tabs, then restart a new node server, the number of clients connected seems incorrect.
For example, I will connect with just one client but the node debugger shows that the server is keeping track of three sockets.
This is a problem because often these orphaned clients will receive messages from the server or timeout, and this messes up the game logic on the server (it was not expecting this many players etc.)
I think the reason this is happening is:
1. Clients in socket.io automatically attempt a reconnect periodically when they are disconnected
2. When closing a tab the sockets associated with that page are not being "flushed" or cleared for some reason.
3. When the server is closed and then started up again, these unflushed clients think "oh, the server is back up, i will try and reconnect"
How can I tell the difference between sockets that have had their tabs closed/were associated with the old server, and new clients attempting to connect to the newly restarted server? Or is there a way for me to ensure the clients get "flushed" when either the server is closed or a tab?
Without any code, I am really only guessing here.
http://socket.io/docs/#sending-and-receiving-events
Above, you will find code and I will copy it. Basically, you need to listen to the 'disconnect' event on the socket and remove your reference of the client from whatever array you are using to keep track of your clients.
socket.on('disconnect', function () {
// remove from list here
});
Connections from the browser will die on tab close and this event will be called when this happens. Yes, if you reopen the page, they will reconnect.
You should create some sort of "handshake" that actually adds a client to your list of game clients. Anyone can technically connect to a websocket. It can be as simple as emitting an "init" message that is empty but at least have something there.
I have a client/server application using nodejs on the server and socket.io as the connection mechanism. For reasons relevant to my application I want to have only one active connection per browser, and reject all the connections from other tabs that may be opened later on during the session. This works great with WebSockets, but if WebSockets is not supported by the browser and XHR-polling is used instead, the disconnection never happens, so if the user just refreshes the page, this is not interpreted as a reconnection ( I have a delay for reconnection and session restoring), but as a new tab, which ends in the connection being rejected because the old connection made by this same tab is still active.
I'm looking for a way to effectively end the connection from the client whenever a refresh occurs. I've tried binding to the beforeunload and calling socket.disconnect() on the client side, and also sending a message like socket.emit('force-disconnect') and triggering the disconnect from the server with no success. Am I missing something here? Appreciate your help!
I've read this question and couldn't find it useful for my particular case.
Solved the issue, it turns out it was a bug introduced in socket.io 0.9.5. If you have this issue just update BOTH your server and client-side code to socket.io > 0.9.9 and set the socket.io client-side options sync disconnect on unload to true and you're all set.
Options are set this way:
var socket = io.connect('http://yourdomain.com', {'sync disconnect on unload' : true});
You can also get "Error: xhr poll error" if you run out of open file descriptors available. This is likely to happen during a load test.
Check the current open file descriptor size:
ulimit -n
Increase it to a high number:
ulimit -n 1000000
I am working with socket.io and node.js. I'm am having problems tracking which users are online because of the few seconds delay before socket IO recognises an XHR-Polling client has disconnected.
If an XHR-Polling client refreshes the page their new connection message seems to precede their disconnection message. This causes confusion when trying to track which users are online.
One solution could be to detect the transport method on the serverside and delay the connection for XHR-Polling clients to ensure that the disconnection functions have been run first.
Has anyone had any experience of this?
The main problem with presence, as #davin and #jcolebrand point out in the comments, is that connections alone can't be relied upon. Network devices can hold on to connections after a user has navigated away from a page. So, you need something else in place to confirm a users presence.
This is something we've added support for in Pusher and we do this using something called Presence Channels.
We manage this using a unique user id, which you (the developer) have to supply when a user connects, in combination with a unique socket id which identifies the connection. Since this unique user id can only occur once within a presence member list it means that that user will only be listed once - even if they have multiple connections open, and thus multiple socket connections.
The same idea can be applied to HTTP connections.
The general approach for this is to use the session to uniquely identify the user. In that way even if they are just a "Guest" you can still identify them as long as they are allowing the use of cookies.
So, the number of users on your system should only ever max at the number of active sessions you have running on your server.
Hope this helps. Let me know if you'd like anything clarified.
I'm developping a chat support solution and the attendent have to know when a client connect. With websocket works fine, but with whr-pooling, sometimes the attendent just disconnect (with 5 seconds in some cases). Sometimes dont heppend. What I do: I just enter the page and wait looking the terminal app.
I'm using nodejs, nowjs
What version of socket.io are you using? I encountered this issue and solved it on this post. It turns out there was a bug introduced in socket.io 0.9.5 on the request sent when the beforeunload event was triggered that prevented the proper disconnection.
In my application, the client is a Javascript set of functions in the browser, and it does some work - for example, playing a clip.
It uses XmlHttpRequest to talk to the server.
However, the server is allowed to abruptly close the connection since there is no other way it seems, to interrupt the client.
Can the client detect, while it is playing the clip, that the connection was closed, and so print a message and erase the page?
Any help appreciated.
thanks,
Anil
If the clip is streamed to the client, you could just stop serving it.
However, it seems like the clip is being downloaded and then played through the browser. In this instance it's probably best to use a watchdog approach as described by CookieOfFortune: Poll the server regularly (once a second or so) and get it to respond with tiny message of confirmation. When the connection is closed, get the server to respond with a negative messgage.
Unfortunately, without using a comet-like system, it's very hard to get the server to 'send' a message indicating session closure.
Bear in mind though, that as soon as the client has downloaded a clip they will be able to play it in full if they want to. Unfortunately there's no way to stop this besides switching to a streaming approach. If securing your content is a priority, I'd suggest making this change.
You can probably poll the XmlHttpRequest object, so just try to send a heartbeat every once in a while to see if the connection is closed. Otherwise, the server would have to send some signal to tell the client it is going to close the connection.
It does seem that the server cannot notify the client that the connection is closed; however the polling method suggested is not as efficient as a notification would have been.
I solved it by specifying that at the NEXT Get request, the client would be told that its session is invalid.
This was implemented by URL rewriting - appending "jsessionid=[id]" on each request sent by the Javascript functions. the servlet stores the current session id.