Is there any option for setInterval()? - javascript

I am reading a file continuously after a some time as
setInterval(function(){
$.getJSON("json/someFile.json", function(data){
// Some code
});
}, 5000);
I am reading this file continuously after a delay as it is getting updated in other part of the code. I want to avoid using setInterval().
Is there any way, by which I will be able to know that the file is updated and read it only when it is updated.

Firstly, setInterval is a native JavaScript method. It does not come from jQuery. Second what you've done is called polling. Meaning that you request some information periodically in order to keep it up to date. The alternative is using a WebSockets. Websockets are a two way connection between the client and the server, which can both push and receive messages. This way, you can send a socket message to the client whenever the file is updated in the backend.

I'm assuming you're talking about client side code. Then no: there is no way to "watch" a json file like you could have a file watcher in "regular" applications. You need either:
Interval-based checking as you're doing now. However, as suggested in comments by #George, you might be better off if you use setTimeout and only re-fire the Ajax request in specific situations (e.g. on success, perhaps not on failures); With your current approach the function may run on the interval, but if it takes longer than the interval timing to respond you get a build-up of requests;
Websockets (potentially with fallback to something like long-polling), perhaps using another library for that + the server-side part of this solution;
No other way I'm afraid.
As a footnote, this hasn't got much to do with jQuery. First, the setInterval is not of jQuery but a regular window function, and second the problem of "watching" a file isn't specific to how you're doing the Ajax call (you're using jQuery, but you could use another lib for it too).

Related

Node JS + Express JS: refresh page from other location

I have the following problem: I want to change one variable on a page. The input comes from another page so:
I'm using Node.js, Express.js and Ejs for this task.
Server - storing the values
Index page - Control page with input fields and send button
Display page - Shows the variable
I'm sending the variable with fetch post to the server. On the server I change the variable with the request body value and when I reload the "Display page" manually I see the new value. The problem is: I need to change it without any manual refresh or other things, because that won't be possible.
There is the possibility with "location.reload()" to refresh it every X second. But that's not the way I want to use, I really just want to refresh it when the variable changes. Is there a function (from express.js for example) I can use for it?
edit: I should mention that this project would be just used in our network and its not open for other users. Like an in-house company dashboard kind of.
So a "quick and dirty" solution can work too, but I want to learn something and wanted to do it the right way though.
This is a very common scenario that has several solutions:
Polling - The display page runs ajax calls in a loop every N seconds asking the server for the lastest version of the variable. This is simple to implement, is very common, and perfectly acceptable. However, it is a little outdated, and there are more modern and efficient methods. I suggest you try this first, and move on to others only as needed.
WebSockets - WebSockets maintain a connection between the client and server. This allows the server to send messages to the client application if/when needed. These are a little more complex to setup than just plain ajax calls, but if you have a lot of messages getting sent back and forth they are much more efficient.
WebRTC - This is taking it to another level, and is certainly overkill for your use case. WebRTC allows direct messaging between clients. It is more complicated to configure than WebSockets and is primarily intended for streaming audio or video between clients. It can however send simple text messages as well. Technically, if you want to persist the message on the server, then this is not suitable at all, but it's worth a mention to give a complete picture of what's available.
The simplest solution that came to mind is to have the server return the updated post in the body, then use that to update the page.
You can also read about long/short polling and Websockets.
One possible solution would be to add page reload code after a successful post-operation with fetch.
fetch(url, {
method: 'post',
body: body
}).then(function(response) {
return response.json();
}).then((data) => {
// refresh page here
window.location.replace(url);
});
Proper solution (WebSockets):
Add WebSocket server as a part of your Node.JS app
Implement subscriptions for the WebSocket, implement function 'state changed'.
subscribe on a method 'state changed' from your client browser app.
call ws server from your express app to update the clients when your variable is changed
Outdated (Polling):
Add express endpoint route: 'variable-state' Call server from your
client every n ms and check whether variable state is changed.
Refresh the page if variable is changed.

Long Polling: How do I calm it down?

I'm working on a simple chat implementation in a function that has an ajax call that invokes a setTimeout to call itself on success. This runs every 30 seconds or so. This works fine, but I'd like a more immediate notification when a message has come. I'm seeing a lot of examples for long polling with jQuery code that looks something like this:
function poll()
{
$.ajax(
{
data:{"foo":"bar"},
url:"webservice.do",
success:function(msg)
{
doSomething(msg);
},
complete:poll
});
}
I understand how this works, but this will just keep repeatedly sending requests to the server immediately. Seems to me there needs to be some logic on the server that will hold off until something has changed, otherwise a response is immediately sent back, even if there is nothing new to report. Is this handled purely in javascript or am I missing something to be implemented server-side? If it is handled on the server, is pausing server execution really a good idea? In all of your experience, what is a better way of handling this? Is my setTimeout() method sufficient, maybe with just a smaller timeout?
I know about websockets, but as they are not widely supported yet, I'd like to stick to current-gen techniques.
Do no pause the sever execution... it will lead to drying out server resources if lot of people try to chat...
Use client side to manage the pause time as you did with the setTimeout but with lower delay
You missed the long part in "long polling". It is incumbent on the server to not return unless there's something interesting to say. See this article for more discussion.
You've identified the trade-off, open connections to the web server, therefore consuming http connections (i.e. the response must block server side) vs frequent 'is there anything new' requests therefore consuming bandwidth. WebSockets may be an option if your browser base can support them (most 'modern' browsers http://caniuse.com/websockets)
There is no proper way to handle this on the javascript side through traditional ajax polling as you will always have a lag at one end or the other if you are looking to throttle the amount of requests being made. Take a look at a nodeJS based solution or perhaps even look at the Ajax Push Engine www.ape-project.org which is PHP based.

adding latency to a web application

I want to slow down my app by adding latency for ajax requests. I have two options: doing it in javascript and doing it server-side. With javascript, I could easily add a setTimeout on my requests but there are about 30 different requests and I'm wondering if there's a better way, with less code.
I want to slow down ajax requests server-side. What's the best way to do it? I'm using about 25 different asmx web services (will be converted to wcf soon) and I'm wondering how to make it so that all requests have 1000ms of latency.
My goal is to change as little code as possible so that I can turn this feature on/off by changing as little as possible.
Thanks for your suggestions.
In case you're wondering why: I'm running on my local machine. I'm going to do a user-testing session and I need to simulate real ajax requests. Without latency, the ajax request happens almost instantaneously.
You could add a
System.Threading.Thread.Sleep(1000)
in the OnRequestBegin-Handler or where ever you can intercept the request before doing the actual work.
you can hook in a timeout event on the server side code before it responds to the ajax request. At least then your ajax's interaction with a latent response is authentic.
If you are using jquery for the ajax call, just go into the jquery code file and add the latency there. Would that work?
Look for this line in the main jquery file:
ajax: function( url, options ) {
Add this code right after:
var ms = 1000 //wait time in milliseconds
ms += new Date().getTime();
while (new Date() < ms) { }
ms is the number of milliseconds to wait
I would put an http proxy in the way which you control and can make slow.
Since I know Perl best I'd use something like http://metacpan.org/pod/HTTP::Proxy and add a filter method that did nothing but wait a second.

tail -f in a webbrowser

I've created a Python script that monitors a logfile for changes (like tail -f) and displays it on a console. I would like to access the output of the Python script in a webbrowser. What would I need to create this? I was thinking about using Django and jQuery. Any tips or examples are greatly appreciated.
First create a python script that monitors the log file for changes. If you only need this for debugging - testing purposes, then it is an overkill to use Django or another web framework. It is very easy to implement Http Web server functionality using sockets. Whenever an Http GET request is coming, serve only the difference from the different request. In order to achieve this you need to store in memory the status of every request coming (e.g.number of last line in the file).
The jQuery part is actually quite easy. Set up a timer with setTimeout function. Something like this will do:
function doUpdate() {
$.ajax({type: "GET", url : tailServiceUrl,
success: function (data) {
if (data.length > 4)
{
// Data are assumed to be in HTML format
// Return something like <p/> in case of no updates
$("#logOutputDiv").append(data);
}
setTimeout("doUpdate()", 2000);
}});
}
setTimeout("doUpdate()", 2000);
You can also create callbacks for error and timeout to report a problem with the server.
I don't have any Python or Django experience but I'd assume you can make a system call like tail in Python and relay the details.
From there, I'd use a jQuery .ajax() call with a javascript setInterval() loop to your Python script and output the results to a div on the web page. Overall a pretty simple solution.
In this instance, you really wouldn't need to use an open tail -f system call because the nature of the JS setInterval() method, the Python script will be called over and over again until the JS clearInterval() method is called. You'll aggregate your script details in either Python or JS depending where you want to do the work. I'd suggestion Python since you'd have more robust features at your fingertips and you would send less data via the AJAX call. Theoretically, there probably shouldn't be too much logic needed in the jQuery code on the front end. Just display the data.
http://api.jquery.com/jQuery.ajax/
http://www.w3schools.com/jsref/met_win_setinterval.asp
Why don't you output the data to a HTML file? You could run a cron job to run your script which would in turn spurt out a HTML file which could be accesses from the browser.
The most voted answer works ok, but there is a more agnostic way to do this.
You can use https://github.com/mthenw/frontail
Just install it and invoke it with the files that you want to watch.
frontail /var/log/syslog /var/log/another_log
then visit http://127.0.0.1:9001
I hope this can help others.

jQuery: Using a single Ajax call, receive progressive statuses instead of one single response?

I'm just wondering..is it possible to receive multiple responses from a single ajax call?
I'm thinking purely for aesthetic purposes to update the status on the client side.
I have a single ajax method that's called on form submit
$.ajax({
url: 'ajax-process.php',
data: data,
dataType: 'json',
type: 'post',
success: function (j) {
}
});
I can only get one response from the server-side. Is it possible to retrieve intermittent statuses? Such as:
Default (first): Creating account
Next: Sending email confirmation
Next: Done
Thanks for your help! :)
From a single ajax call, I don't think it is possible.
What you could do is check frequently where the process is (it's what is used for the upload bars in gmail for example). You do a first ajax request to launch the process, and then a series of ajax request to ask the server how he is doing. When the server answers "I'm done", you're good to go, and until that you can make the server respond and say the current state.
There is something called comet which you can set up to "push" requests to client, however it is probably way more than what you are wanting to invest in, time-wise.
You can open up a steady stream from the server, so that it continues to output, however I'm not sure how client-side script can handle these as individual "messages". Think about it like a server that outputs some info to the browser, does more work, outputs some more to the browser, does more work, etc. This shows up more or less in real time to the browser as printed text. It is one long response, but it is still one response. I think ajax only handles a response once it finished being sent, but maybe someone else will know more than me on the topic.
But you couldn't have the server output several individual responses without reloading itself, at least not with PHP, because once you start outputting the response, the response has begun and you can't chop that up without finishing the response, which happens when the script is done executing.
Your best bet is with the steady stream, but again, I'm not sure how ajax handles getting responses in chunks.
Quick Update
Based on the notes for this plugin:
[http://plugins.jquery.com/project/ajax-http-stream]
things don't look promising. Specifically:
Apparently the trend is to disallow access to the xmlhttprequest.responseText before the request is complete (stupid imo). Sorry there's nothing I can do to fix this
Thus, not only can you not get what you want in one request, you probably can't get it multiple requests, unless you want to break up the actual server-side process into several parts, and only have it continue to the next step when an ajax function triggers it.
Another option would be to have your script write it's status at specific points to another file on the server, call it "status.xml" or "status.txt". Have your first ajax function initialize the process, and have a second ajax function that queries this status file and outputs that to the user.
It is possible, but it has more to do with your backend script. As Anthony mentioned there is a tech called comet. Another term I've heard is called "Long polling". The idea is that you delay the time in which your php(insert language of choice) script finished processing.
In php you can do something like this:
while($response !== 'I'm done'){
sleep(1);
}else{
return $some_value;
exit();
}
This code stops your script from completely finishing. sleep(1) allows the script to stop and lets the server rest for 1 millisecond, before it loops back through. You can adjust the sleep time based on your needs. In php the amount of time the script sleeps is not counted agains your server timeout time.
You'll obviously need to make more checks for you code. You'll probably also want to allow for an abort script call. Something like sending a get request to kill the backend script. Maybe on the javascript unload event.
In the tests that I've done. I made the initial ajax call, and when the value was returned, I made another ajax call, that way your back end script wont time out.
I've only played around with this on my local server, so i'm not sure how real world this is, but it works.

Categories

Resources