Control browser javascript execution from command line - javascript

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

Related

{node / discord js} Restarting bot's entire script on error

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.

Keep Node Server running "watching" for things to occur

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

How do I Implement a Node.Js server-side event listener for Firebase?

I'm trying to listen for data changes in my firebase using firebase's package for Node. I'm using the on() method which is supposed to listen for changes non-stop (as opposed to once() method that only listens to the first occurrence of a specific event ) My listener.js file on the server is exactly like this:
var Firebase=require('firebase');
var Ref= new Firebase('https://mydatabase.firebaseio.com/users/');
Ref.on('child_changed',function(childsnapshot,prevchildname){
Ref.child(childsnapshot.key()).push("I hear you!");
} ) ;
But it only works the for the first occurrence and throws a fatal memory error after a second occurrence.
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
I'm very new to server side programming and don't know what to do. I must be missing something important. Should I set up special server settings with node first? or maybe make a daemon that runs a script with once() method every second or so ?
I'm pretty sure you're creating an endless loop here:
You push a value to https://mydatabase.firebaseio.com/users/
the on('child_changed' event fires in your script
your script pushes a new child under the value
so we go back to step 2 and repeat
It will happen quite rapidly too, since Firebase clients fire local events straight away.
It looks like you're trying to create a chat bot. Which means you more likely want to create sibling messages:
var Firebase=require('firebase');
var ref= new Firebase('https://mydatabase.firebaseio.com/users/');
ref.on('child_changed',function(childsnapshot,prevchildname){
ref.push("I hear you!");
}) ;
Note that it is pretty inefficient to use StackOverflow to debug code. Since you seem to be on Windows, I recommend installing Visual Studio and its node tools. They have a great debugger that allows you to step through the code. Setting a breakpoint in your callback (so in the line with ref.push), will quickly show you what is going wrong.

How do I send a channel message using channel.trigger with websocket-rails gem

I'm building a simple real-time chat app to learn how to use websockets with RoR and I don't think I'm understanding how channels work because they're not doing what I expect. I can successfully send a message to my Rails app using the dispatcher.trigger() method, and use my websocket controller to broadcast a message to all clients that subscribe to the channel. That all works fine. What does NOT work is using a channel (via the channel.trigger() method) to send a message to other clients. The websocket-rails wiki says...
Channel events currently happen outside of the Event Router flow. They
are meant for broadcasting events to a group of connected clients
simultaneously. If you wish to handle events with actions on the
server, trigger the event on the main dispatcher and specify which
controller action should handle it using the Event Router.
If I understand this correctly, I should be able to user the channel.trigger() method to broadcast a message to clients connected to the channel, without the message being routed through my RoR app, but it should still reach the other connected clients. So here's my code...
var dispatcher = new WebSocketRails('localhost:3000/websocket');
var channel = dispatcher.subscribe('channel_name');
channel.bind('channel_message', function(data) {
alert(data.message);
});
$("#send_message_button").click(function() {
obj = {message: "test"};
channel.trigger('channel_message', obj);
});
With the code listed above, I would expect that when I click the button, it sends a channel message using channel.trigger() and the channel_message binding should be executed on all clients, displaying an alert that reads "test". That doesn't happen. I'm using Chrome tools to inspect the websocket traffic and it shows the message being sent...
["channel_message",{"id":113458,"channel":'channel_name',"data":{"message":"test"},"token":"96fd4f51-6321-4309-941f-38110635f86f"}]
...but no message is received. My questions are...
Am I misunderstanding how channel-based websockets work with the websocket-rails gem?
If not, what am I doing wrong?
Thanks in advance for all your wisdom!
I was able to reproduce a working copy based on an off-the-shelf solution from the wiki along with your very own code.
I've packaged the whole thing here. The files you might be interested are home_controller.rb, application.js and home/index.html.erb.
It seems your understanding of channel-based websockets is correct. About the code, make sure to load the websocket javascript files and to enclose your code inside a document.ready. I had the exact same problem you're having without the latter.
//= require websocket_rails/main
$(function() {
// your code here...
});
Let me know if it works. Best Luck!

What is the best way to implement idle time out for web application (auto log off)

I want to implement an idle time-out for the web application that we are building. I had earlier achieved this using AsynchronousSessionAuditor from codeplex, which essentially looks for the formsauthentication and session cookie timeout by constant polling.
But it has a draw back of not respecting the client side events, it will look for only last postback to decide when to log off.
The jquery plug jquery-idle-timeout-plugin from erichynds solves this issue of client side events but suffers from another drawback that is not able to recognise user is active on some other tab.
Is there anyone already fixed the TABBED browsing issue with jquery-idle-timeout-plugin already? Or is there any better approach of application time out for web applications (by the way this web app is build using asp.net f/w)
If I understand your question right, it is not possible, since there are no events triggered in javascript for activity outside of the current window/tab.
Unless you have a addon to go along with your website for each browser, which could monitor all activity in the browser, but that is not really a practical approach.
Well, you'd have to code it by hand, which is not really hard. You can use the onfocus and onblur functions to do something like this:
$(function() {
window.isActive = true;
$(window).focus(function() { this.isActive = true; });
$(window).blur(function() { this.isActive = false; });
showIsActive();
});
function showIsActive()
{
console.log(window.isActive)
window.setTimeout("showIsActive()", 2000);
}
function doWork()
{
if (!window.isActive) { /* Check for idle time */}
}
If you make a little search you can find that varaieties of this question have already been asked and answered, you can probably find a solution you can implement with one of the plugins you mentioned.
Try:
Run setTimeout only when tab is active
or
How to tell if browser/tab is active
EDIT--> ADDED:
Or I'd try a different approach. You could create a cookie with some hash and save that hash in your DB with a timestamp that updates whenever the window is active (you could check every 5 seconds or something, it's not an intensive request)
Then, do another check before(but in the same request) to see how much time has passed since the last timestamp and log them out if necessary.
it won't log them out isntantly when time has passed, but it will when they try to access the site either by opening it again or by focusing on the tab/window.

Categories

Resources