I need to be able to detect when a user has lost connection to the socket, it doesn't seem that socket.on("disconnect") is being called when I just close my laptop, so it doesn't run the ajax call that needs to run in order to update the database to mark the user as offline. How could I check if the connection has been closed or whatever?
As mentioned here https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO, Socket.IO has it's own heartbeat implementation.
But the defaults are a 25s interval and a 60s threshold for a lost connection.
So my advice: Set the defaults as you expect on testing. Otherwise you may miss the threshold.
Example:
socket.set("heartbeat timeout", 10);
socket.set("heartbeat interval", 5);
we came across this too and as mentioned above use our own heartbeat timer.
For example the server will emit a heartbeat every 5 seconds (we simple send out server time). The client has an 11 second timeout so it has 2 chances to catch the heartbeat. If it receives the heartbeat we reset the timer. If we miss both heartbeats the timeout function is run and you do whatever you want there.
Fairly straightforward.
Related
Currently, I want to check status of socket when network is down with connected property. But i have an issue when unplug network cable, the connected status still true for 20 seconds or more. How can i get the status immediately ?
You'll have to set the timeout option, which by default is set to 20.000 MS (20 seconds). You can find a lot of information here: http://socket.io/docs/client-api/#
I would disrecommend making it absolutely instant though. Most if not all networks have some instabilities, which are accounted for by the timeout delay. It's there for a good reason. Maybe just make it a bit shorter?
I think this question is due to a lack of understanding on node, but i'm working on created a motion sensor with the raspberry pi and node.
I don't understand how to keep my node server running. I can get it to work as intended using setInterval but I don't think this is how I should be doing it.
Basically I want to be able to start the program with node index.js and have it continue watching the GPIO pins that the sensor is connected to see if something happens. If something happens then it does something, but keeps watching the sensor in case more happens.
What I have done to keep it running is similar to this:
var foo = require('require necessary things up here');
setInterval(function(){
//code for detecting sensor stuff here
}, 1000)
This works, but I know I don't think it's the right way to do it.
If I do something like the below it just executes the functions, logs to the console, but doesn't watch for changes and just exits out.
var foo = require('require necessary things up here')
function checkForSensorStuff(){
//code for detecting sensor stuff here
console.log('checking stuff')
}
How can I keep the server running so that it just continually watches for changes in a function without using setInterval?
A node process exits when it has nothing else left to do. You start a node process by running a startup script line by line. When that script finishes executing, if there's nothing else to do (no timers, no open sockets listening for incoming connections, etc...), then it shuts down because there's nothing left that could cause an event and cause some action on the server.
So, if you want your server to continue running, you have to give it some way for future events to occur. As you've discovered a recurring timer is one way to do that. There should be no reason to use a timer purely for keeping your server running. Instead you need to configure something in your server that will trigger events in the future. If you don't have anything that will cause future events, then you may need to use setInterval() to regularly poll some status to decide if there's something waiting to do.
If you're trying to monitor GPIO status on your Raspberry Pi in node.js, you can use the pigpio library and it will offer an event driven way of watching for GPIO changes. This should automatically keep your server running.
Another option for getting events upon GPIO changes is the onoff library.
I have a Raspberry Pi being used as a temperature controller that reads two GPIO temperature probes. I'm just using a setInterval() timer to poll the temperature readings every 10 seconds and that works just fine too.
I don't understand how to keep my node server running
You need to open an handle to a resource like a socket or a file. If there is no active handles opened, node exits. In your example setInterval is timer which prevents node to exit.
see also process._getActiveHandle
https://github.com/myndzi/wtfnode
I'm using this AutobahnJS code in node to receive data from a service. It works great, getting multiple events per second. When my internet temporarily disconnects Autobahn does not detect the lost connection and does not write "Websocket connection dropped" to console, it just hangs. Indefinitely.
Is there a timeout one can set, if no data arrives after 1 minute, reconnect? Or can I use a setTimeout function to ping a server and if no pong returns close the connection and try to reopen it?
I googled till my fingers were bleeding, but I didn't find a straightforward answer to this question. Thank you very much!
connection.onopen = function(session) {
session.subscribe(arg, someEvent);
}
connection.onclose = function() {
console.log("Websocket connection dropped");
}
connection.open();
It is not possible to recognize an unclean disconnect without some data being sent. The WebSocket ping/pong mechanism at the protocol level is not exposed in the browser, and Autobahn|JS does not have any different handling when running in Node.js.
For the time being, you need to implement your own ping/pong mechanism at the application level.
I use Socket.IO 0.9.16 to establish a connection:
io.connect(url)
However, when the server dies, it takes 2 minutes timeout to detect error with the server.
I already tried to reduce timeout to 5s by setting:
io.connect(url, {'timeout': 5000, 'connect_timeout': 5000})
But no success... How can I do this?
The challenge here is that there are a bunch of different settings that interact with each other and some retry logic that all make a socket.io timeout not what you would normally expect. I should add that I am familiar with socket.io 1.0+, not 0.9 though this probably applies to both.
Lets review how a socket.io connection works.
It attempts to make the initial connection.
If that succeeds, then you're done with the connection.
If that connection attempt does not return immediately, it will wait the timeout value that you pass in the initial options for a connection result.
If your server is down, the connection attempt will likely fail quickly. This will result in a connect_error and if you register for that message on the socket with socket.on('connect_error', function() {...});, you will see that connect_error event.
This connect_error is not a timeout. So, if the connection fails quickly (which it usually does when the server is just down), then you never get the regular timeout and the timeout argument you pass to io({timeout: 5000}) really doesn't come into effect. That only comes into effect when a connection to a server is just taking a long time (like an overly busy server or a server that accepted the TCP connection, but is really slow at responding). This is not usually what happens when a server is just down or unreachable.
So, after socket.io gets a connect_error it marks this socket.io connection for retry.
The delay before retrying is based on a whole bunch of things. Presumably, the reconnectionDelay option is part of the formula, but in looking at the code, there is also a backoff algorithm that lengthens the time between retries the more times it has retried. So, suffice it to say, there's some algorithm that calculates a given delay before retrying that varies for each retry.
Then, after that calculated delay, it tries to connect again. This essentially repeats the process starting at step 1 again.
As best I can tell, by default it keeps retrying forever. There is an option you can pass reconnectionAttempts that specifies the maximum number of reconnection attempts. This default to infinity if you don't pass it. But, if you pass 10, then it will give up after 10 successive connection failures.
If you specify reconnectionAttempts, then after that many unsuccessful connection attempts, you will get a reconnect_failed event on the socket and it will give up.
As best I can tell, there is no traditional timeout in the way that you are looking for where it would connect, attempt some retries, then give up after x amount of time. The timeout option applies only to a single reconnect attempt and not to the total amount of time it keeps trying to connect.
In a sample test page I've been experimenting with, I was able to implement my own traditional connection timeout like this:
var socket = io(...);
// set connect timer to 5 seconds
socket._connectTimer = setTimeout(function() {
socket.close();
}, 5000);
socket.on('connect', function() {
// socket connected successfully, clear the timer
clearTimeout(socket._connectTimer);
});
This will wait a maximum of 5 seconds for a successful connection, regardless of how long a connection attempt takes or many reconnect attempts occur in that span of time. After 5 seconds without a successful connection, it shuts down the socket.
In my test app, I can see socket.io happily retrying the connection over and over again until after 5 seconds, my timer fires, I get notified of the "timeout" and I close the socket and it stops trying to retry any more.
I think it is connect timeout
io.connect(url, {'timeout':5000, 'connect timeout': 5000})
Maximum HTTP Request execution time is 120sec in Node.js , how can i increase max execution time on http get/post requests?
NOTE:I'm using expressjs framework
http://nodejs.org/api/http.html#http_server_timeout
server.timeout
Number Default = 120000 (2 minutes)
The number of milliseconds of inactivity before a socket is presumed to have timed out.
Note that the socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections.
Set to 0 to disable any kind of automatic timeout behavior on incoming connections.
You would use server.setTimeout(0); to get what you're after. It's documented here. Although I can't figure out why you would need to change this except for troubleshooting.