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
Related
I have a working WebRTC JavaScript application. Here is the problem: if during a web call there is a bad network connection, the call is stopped without WebRTC attempting to reconnect.
I would like to improve the code of my application by adding an automatic reconnection attempt system, however, in order to do so I need to understand some theory about WebRTC (and I think this can be very useful for many other developers).
Here are my questions:
Does WebRTC have a native functionality to attempt reconnection if the network is bad or should I listen for some "disconnection tigger" and call "a function" to start a new connection from zero?
If things cannot be done magically, what is/are the right "disconnection tigger/s" and "the function" from which the reconnection attempt process should restart? Is there something that can (or should) be taken from the previous connection?
I have read about an {iceRestart: true} parameter. Should this be used for the first call (then WebRTC will magically handle disconnection by attempting to reconnect) or should I use it ONLY when my code attempts to reconnect (on the 2nd, 3rd times...)?
What is the difference between connectionState "disconnected", "failed" and "closed" and does it have something to do with attempting to reconnect with bad network?
What is the best way to avoid attempting to reconnect in an infinite loop if there is no hope to reconnect (i.e: internet completely down)?
What is the difference between oniceconnectionstatechange and onconnectionstatechange? which is relevant in my case?
Thanks!
Luca
I was able to find the (JavaScript) solution through experimenting...
1) Does WebRTC have a native functionality to attempt reconnection if the network is bad or should I listen for some "disconnection tigger" and call "a function" to start a new connection from zero?
Yes, it does it by default in JavaScript, unless your code handles disconnection by proactively terminating the call through additional lines of instructions.
2) If things cannot be done magically, what is/are the right "disconnection tigger/s" and "the function" from which the reconnection attempt process should restart? Is there something that can (or should) be taken from the previous connection?
Things already happen under the hood (by magic). If the code terminates the call, it is probably because the disconnection trigger (ICE connection state = disconnected OR connection state = disconnected) triggers some additional code from the app you copy/pasted from somewhere.
3) I have read about an {iceRestart: true} parameter. Should this be used for the first call (then WebRTC will magically handle disconnection by attempting to reconnect) or should I use it ONLY when my code attempts to reconnect (on the 2nd, 3rd times...)?
Not useful in this scenario.
4) What is the difference between connectionState "disconnected", "failed" and "closed" and does it have something to do with attempting to reconnect with bad network?
You have to listen for connectionState = disconnected, the other ones don't matter for this purpose.
5) What is the best way to avoid attempting to reconnect in an infinite loop if there is no hope to reconnect (i.e: internet completely down)?
No problem, the reconnection WebRTC handles automatically will not cost anything in terms of signaling, therefore, you can try to reconnect as many times as you want, the user will eventually exit the call on his own if things are too slow.
6) What is the difference between oniceconnectionstatechange and onconnectionstatechange? which is relevant in my case?
No difference in this case, the only difference is that the ice state change is triggered right before the connection state change.
--
I hope this will be helpful to somebody!
I want to refresh a page in a browser tab using keyboard shortcut or CLI command when the browser window is not active (i.e. I'm working on different display). The webpage that have to be refreshed is well under my control, so I can inject any javascript there. Scrolling location should be kept after the refresh. My idea is to include simple javascript on that page that will wait for some outside event, i.e. through socket, and when this event happens, run location.reload(true). Then I can communicate with this javascript from the command line (shell) script and assign keyboard shortcut to this command line script if needed. I'm pretty sure it's possible because there are lots of tools that allow this (e.g. LiveReloadX). I cannot use such tools because I don't want to automatically refresh the window when something changes, I want to do it by explicit command. It seems that it should be really simple, but I cannot find the solution so far. So, my question is: how to make javascript running in the browser to be controlled from the command line?
There's two parts to getting your solution done - the server running on your command line and the client running on your webpage.
Client
In your browser, you want to initialize a WebSocket client. MDN has a great example to get started with this, and I added your intended functionality of refreshing the page:
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
location.reload(true)
});
Server
There are many different ways to set up a WebSocket server and choosing the one that works best for you is probably too broad for an answer on this site. I did some quick research, and it looks like websocketd is a great way to wrap an existing command line program that uses standard in/out into a WebSocket server. You would need to implement a command line program that listens for your refresh shortcut and then writes a message to standard out. Then, you would wrap it with websocketd and run it from the command line:
websocketd --port=8080 ./your-shortcut-listener.sh
So I'm trying to have my bot restart ENTIRELY on encountering an error. The reason why I don't just let it sift through connection errors is because, whenever I encounter an internet issue, code starts repeating multiple times since the original node process hasn't been terminated, which technically I could fix but other connections to external apis stop working too. So ignoring fixing singular issues, I just want to restart entirely.
What I'm doing currently is using node child_process, with this function:
spawn(process.argv.shift(), process.argv, {
cwd: process.cwd(),
detached : true,
stdio: "inherit"
});
process.exit();
I do know stdio inherit does nothing, since its exiting the parent process, but it doesn't really change anything to put it to ignore so i've just left it. Basically this works in theory, if I use a command to execute this, i can do it over and over and over and it will work fine, singular discord client, no repeats, it's up, i just can't monitor it since my original terminal is disconnected, and I can use a command to exit the current process so it's not stuck since I don't have a terminal to ctrl-c. But once put in practice, executing the function in bot.on("error") by disconnecting my internet seems to work, it ends the first process, but upon regaining internet there is no client connected.
My guess here: bot.on("error") will not be re-executed in the next process due to no discord client being made.
So I don't know if I'm making this too complicated or if I need to add a lot more. If this is the best way to do it then all I would need to solve is to wait until I have internet back and then make a new process or something like that. I'm not educated in fiddling with node so if any answers could be beginner friendly (mainly for node) i'd really appreciate it.
bot.on("error", (err) => {
process.exit(0)
});
Should work, it'll restart the bot when there's an error.
Unsure what you mean by
My guess here: bot.on("error") will not be re-executed in the next process due to no discord client being made.
As long as you bot it in the same code as your startup, it'll restart the bot.
If you use a batch-file to run your bot simply add :a before the node . and goto a at the end.
I have a node app that connects to a server, so that my code can easily send data to it since I just leave the connection open constantly. But the problem is that the app never exits because the connection is still active, even after it's done being used.
The problem is there isn't one solid code path, so there isn't one place that I could end the connection. Is there a way to tell node to exit as soon as all the other code is finished, even though the connection is still open?
I'm going for something like fs.watchFile
process.exit(exitCode)
http://nodejs.org/api/process.html#process_process_exit_code
Aside: It really sounds like the code is due for a refactor with clear socket handling in mind. Refactor early, refactor often.
I have an application which uses an open JQuery Ajax connection to do long-polling/comet handling of updates.
Sometimes the browser and the server lose this connection (server crashes, network problems, etc, etc).
I would like the client to detect that the update has crashed and inform the user to refresh the page.
It originally seemed that I had 2 options:
handle the 'error' condition in the JQuery ajax call
handle the 'complete' condition in the JQuery ajax call
On testing, however, it seems that neither of these conditions are triggered when the server aborts the query.
How can I get my client to understand that the server has gone away?
Isn't it possible to add a setInterval() function that runs every few seconds or minutes? That way you can trigger a script that checks whether the server is still up, and if not, reset the comet connection. (I don't know what you use for the long-polling exactly though, so I don't know if it's possible to reset that connection without a page reload. If not, you can still display a message to the user).
So something like this:
var check_server = setInterval(function() {
// run server-check-script...
// if (offline) { // reset }
}, 60000);