Persisting a JavaScript setTimeout function call across postbacks as user browses application - javascript

I believe I can use utilize the following functions to create delayed JavaScript alerts:
setTimeout(), clearTimeout(), setInterval() and clearInterval()
But how can I use them accross postbacks. For example:
A user has a list of reminders stored in the database. When user logs into site I can access those reminders and call something like:
setTimeout(function() { alert("Reminder 1"); }, 10000);
Depending on when the reminder due date/time is.
However as the user switches pages before the alert notification happens I believe the setTimeout call won't persist.
Is the only way to get this to work to look up the users reminders on every single postback and do a setTimeout on every page or in some sort of master page?

This is not really the way to do this. If your trying to build some sort of notification system then ideally it should be driven server side.
In a normal multi-page site every time you render a page the server would check for notifications and then in your template render an alert or some UI feature that tells the user they have notifications.
That set-up won't be active, IE if a new notification is posted on the server the client page won't know about it. Unless you use a notification message api for example pubnub.
Something like pubnub would let you send the message to your page, and in your JS code get a callback, so you can render it in your dom.
Since you have a multi-page app you would need to fetch / request for the notifications on every page render. Running a timeout to trigger for an ahead of time moment is not an ideal solution.
Another way to do it is to poll your server from your js code say every 5 mins and ask for notifications.
That has a price tag on all those repeated calls to your server. The best bet is to use something like pubnub but that comes at an extra laden of code server side to make it work.

Related

Pubnub: Background Processes for an Auction App Development

Hello I am developing an auction app like tophatter.com. I want to implement an application that has background process in it. I want this process to run forever until I stop it
http://eoction.com thatss our current site. The problem on our site when we refresh the page the auction also restart. We need something like a continuous process like tophatter.com if you refresh the page it will load the updated auction process.
I found this great service called pubnub. I am thinking we need a background process for this? This will process the auction on the pubnub blocks and then when we visit the site we will just need to query on its updated process?
Does pubnub support something like this?
PubNub Web Page Best Practices
When user refreshes your web app page or navigates to another page there are things you need to consider as a web app developer no matter what technologies you may be using. I will address, at a high level, the things you need to do when PubNub is integrated into your web page.
Restore Parameter
Whether the user interrupts your connection to PubNub or it is a network failure, you will want PubNub to reconnect and continue where it left off as much as possible. The PubNub JavaScript SDK has a initialization parameter called restore that when set to true, will reconnect to PubNub and get missed messages after the connection is dropped and reestablished.
var pubnub = new PubNub({
subscribeKey: "mySubscribeKey",
publishKey: "myPublishKey",
ssl: true,
uuid: getUUID();
restore: true
});
Reuse UUID
It is important to reuse the same UUID for each end user as this will allow PubNub to identify that user uniquely when it comes to Presence so that it doesn't produce new join events for the same end user. The PubNub JavaScript SDK actually generates a UUID and stores it in localStrorage and reuses it by default but very likely you have your own UUID that you would like to use for each of your end users.
Last Message Received Timetoken
If the network disruption is brief as is the case with a page refresh or page navigation, then missed messages are retrieved when restore:true is implemented in the init as stated above. But when the user is offline for more than say 5 minutes, you may want to retrieve missed messages on one or more channels. The best way to do this is to keep track of the timetoken of the last received message by storing it in localStorage every time a message is received via subscribe callback. When the user comes back online and it is has been more than 5 minutes since they were last online, call history using this last received message timetoken on each channel that you need to get missed message from.
Subscribe to Channels
Finally, you'll want to make sure that the user is subscribed to the channel they expect to be based on what their state prior to the connection disruption. If it is a page refresh, you likely just want to resubscribe them to the same list of channels. To do this, you just need to keep a list of channels they are currently subscribed to, once again, in localStorage. If the user navigates to a new page and this causes a full page reload (modern web apps should not require this, but...) then you may want to unsubscribe from some channel(s) and subscribe to new channel(s), it just depends on what that page navigation means to your app. Modern web app frameworks do not require full page reload for page navigation since the web app acts more like a desktop app than older web apps. And again, if the the user was offline for quite some time (more than 5 minutes) then it may not make sense to subscribe them to the same channels that they were subscribed to before. Really depends on your use case.
And by the way, Tophatter uses PubNub ;) but all of the above are generic best practice guidelines and recommendations and is not referencing any one app in particular.
EDIT: To address you question specifically, as pointed out in comments below...
You can't implement long-running process in PubNub BLOCKS (not currently, anyways), so you will need a server process for this. When the user refreshes the page, you just need to hit your server for current state. If using PubNub to keep this progress bar updated in realtime, you just subscribe to that channel that is sending the state of that progress bar and update your client. Using the same best practices I provided above are still necessary.

Node.js event when Facebook page posts

I'm using Node.js to build a site which involves getting posts from a public Facebook page.
I currently have the server updating my sqlite3 database from Facebook every n hours which works fine but I was wondering if there is some way I can set up an event which calls the update function whenever the page makes a post?
This would mean the site was always up to date with the page and there wouldn't be the delay of waiting until the next update time
You can use Webhooks: https://developers.facebook.com/docs/graph-api/webhooks
...those can only be used if you manage the Page though, there is no way to subscribe to changes to a Page you don't own.

Php long script with client side callback

I'm have a very long process in a php script (generate a huge pdf).
I have a button in my HTML page that launches the php script and I'd like to show a kind of progress bar or at least an animated gif and when the php script is over, display the generated pdf.
The generation of the pdf may last 15 minutes so the php engine exits in timeout and the browser too.
I there a way to declare a kind of client-side callback that would be invoked as soon as the server side process is over ?
Thanks for your replies
Edit :
Thanks for your replies :)
If I well understand, I must launch the process on server-side and "detach" my client i.e do not wait untill the process is over. Instead, my client should periodically check the progression of server-side process. Right ?
If so, I may use the following scenario :
The client sends an ajax request to the server. The server launches
the process and returns a guid to the client. This guid identifies
the job.
The client periodically checks the progression of the job
via an Ajax request, from its guid.
Once the job is over, the client can issue a last Ajax query to
download the PDF
That means that the server must save the generated PDF on its disk and wait for the final Ajax request to send the file and delete it, right ?
For something as long as 15 minutes, I wouldn't even use web sockets for this. 15 minutes is a long time and there's really no telling what the user is going to be doing in the meantime. A disconnected notification process is probably going to be more reliable in this case.
Consider something like:
User initiates process, whereby a record is stored in the database "queueing" the process to take place.
User is immediately presented with a page indicating that the process has been queued and that they can continue to use the application.
A separate application which runs periodically (every minute? every few minutes?) checks for "queued" processes in the database, updates their status to "in-progress" (so subsequent runs don't also pick up the same records), and processes them.
As each process completes, it's either removed from the database or updated to a "completed" status.
The user is otherwise notified that the process is complete.
This final notification can be done a number of ways. An email can be sent to the user, for example. Or consider a user experience similar to the Facebook notification bar. Each page in the website can check for "completed" processes when the page loads and present a "notification" in the UI which directs the user to the result of the process. If users spend a lot of time on any given page then this would be a good place to use web sockets or long polling via JavaScript to keep checking for completed processes.
The main thing is to separate the user interface from the long-running process. Web applications by design aren't suited for processes which run for that long. By separating the concerns the web application can focus just on the user interface and the command-line application can focus on the processing. (As an added bonus, this would prevent users from over-loading the server with too many concurrent processes. The command-line application can just run one record at a time, so too many concurrent processes just slows down the response, not the server.)
as #David said, but no one has covered the progress bar, the implantation of this depends on what you know ( you being the application creating the pdf ).
Do you know the size of the pdf when complete.
Do you know how long
it will take to generate.
Do you have code where you can hook into
to update the progress.
The application needs a way to know when to update the completed percentage, and by how much. If you can do that then you can either store the progress in the database with the script that crates the PDF and read it on a user facing page, or store it in a file, etc..
jQuery UI progress bar is easy to use, but you will have to know what percentage is done to be able to tell the end user.
After that it is a pretty simple matter of using ajax (jquery $.post ) and a file, that's how i do it. I just wright a simple text file with a number representing the completion percent. Load it via ajax and feed it to the jquery ui progress widget.

How to update asynchron pages upon event from other client?

I'm currently fooling around with AJAX. Right now, I created a Markdown previewer that updates on change of a textarea. (I guess you know that from somewhere... ;-) ).
Now, I'm trying to figure out, how to update a page upon an event is fired from another client. So to say an asynchron message board. A user writes something, an event is called, the post is written.
But on the other clients' pages, the new post is of course not yet available until they reload and get the updated list of posts from the database.
Now, how can you get this to work asynchronously? So in that moment when one client does something, the other clients all get to know that he did something?
I don't think this can be done completely in AJAX, but I also have no idea whatsoever how to implement this on server-side, as it would require a page reload to inform the other clients of the event.
I'm thinking of creating a file or database entry that hashes the current state of data. Whenever a client loads the page, he saves this hash. Then, a timer (does this exist in JavaScript?) checks for the hash every few seconds.
As soon as anyone changes the databse, the hash is recalculated. If the script sees that the hash was changed and is different to the one saved, it reloads the contents form the database and saves the new hash.
Is that even going to work?
Polling that is light as possible is really the best solution here. Even if you did use a socket or something... That's still basically a live connection waiting around that will likely have to poll itself (albeit in a more effecient way).
20 queries in 10 minutes that have responses like {"updates":false} shouldn't even be putting a dent in your application. I mean imagine someone browsing your site requesting 20 pages and the related images/scripts/etc (even if some caching is involved), there could easily be hundreds of requests requiring all sorts of wasted database queries to information to be displayed on the page they don't actually care about.
You could use polling. For example each client might be sending continuous AJAX requests to the server say each 30 seconds to see if new posts are available and if yes, show them:
setInterval(function() {
// TODO: Send an AJAX request here to the server and fetch new posts.
// if new posts are available update the DOM
}, 30 * 1000);
On the other hand when someone decides to write a new post you send an AJAX (or not AJAX) request to the server to store this post in the database.
Another less commonly used approach is the concept of Comet and the HTML 5 WebSockets implementation which allow the clients to be notified by the server of changes using push.

how to update a Django page without a page reload?

My Django app displays data from a database. This data changes without user intervention, i.e. behind the scenes. Whenever it changes, I would like the webpage to update the changed sections without a full page reload.
Obviously AJAX springs to mind. When the page is loaded initially (or manually, fully re-loaded later on), the rendered template loads a JavaScript that runs window.onload = update("all"), update(...) in turn triggers a number of XMLHTTPRequests which again return data that gets transformed into HTML pieces for the corresponding sections. All works fine. At the initial page load.
Now I find myself in a Python function that saves a new object to the database.
How do I tell the browser to run update(...) ?
Do I need to somehow manually issue a request to a url that is mapped to a view which in turn renders a template that contains the JavaScript code to run update(...) ??? Oh my!
I feel like I'm not following the usual approaches.
Maybe I'm just standing to close in front of the problem.
Can anyone help me ?
2021 update: Use channels: https://channels.readthedocs.io/en/latest/
You have two choices
Have the browser poll using setTimeout()
Look into Comet -- this is a technique for pushing data from the server to the browser.
Here's an article on Comet in Django
two approaches:
just update the database and wait until the next AJAX query. That means it should do the query periodically, you'll have to balance between immediacy and server load. It helps a little if you can do a cheap query to just verify if there has been an update. Maybe make that check rely only on memcached instead of going to the DB
use comet. In short: the client does an AJAX query asking for the update. the server sees there's no update, so it doesn't answer. Instead, the connection is kept open for a long time. Eventually either the update comes and the server finally answers, or the client times out and kill the connection. In that case, the client should immediately reissue the query to keep waiting for the update.
You can also use The Websocket API https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.

Categories