How can I implement notification system with jQuery? - javascript

I have a notification zone that I want to be updated when someone sends a message for example using jQuery or Ajax (my database is in a soap server) I want to do the soap call every second or so, how can I do that?

You could use a simple setInterval structure to execute AJAX calls at predefined intervals. Something like this:
setInterval(function(){
$.get('ajax_responder.php',dataObj,function(){
// ajax callback
// here is where you would update the user with any new notifications.
});
},5000);
The previous code will execute an AJAX request every 5000 miliseconds (every 5 seconds).
References:
$.get()
setInterval()

Instead of setInterval(), I would strongly suggest to use setTimeout().
MDN explanation:
If there is a possibility that your logic could take longer to execute
than the interval time, it is recommended that you recursively call a
named function using window.setTimeout. For example, if using
setInterval to poll a remote server every 5 seconds, network latency,
an unresponsive server, and a host of other issues could prevent the
request from completing in its alloted time. As such, you may find
yourself with queued up XHR requests that won't necessarily return in
order.
For such cases, a recursive setTimeout pattern is preferred:
(function loop(){
setTimeout(function(){
// logic here
// recurse
loop();
}, 1000);
})();
In the above snippet, a named function loop is declared and is immediately executed.
loop is recursively called
inside setTimeout after the logic has completed executing. While this
pattern does not guarantee execution on a fixed interval, it does
guarantee that the previous interval has completed before recursing.

The best way for real-time web is node.js.
Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
But you can do it by setInterval or setTimeout, put an Ajax call in your interval.
var intval = setInterval( function()
{
$.get('url.php', {data1: "value1", data2: "value2"},
function(response)
{
// response
});
}, 1000);

Related

jQuery check server updates in a setInterval function - what else can be used?

I want to create the code which will check if e.g some new muser messages appeared and show its count. I know it's simple - just make an ajax calls in the setInterval function:
$(document).ready(function () {
setInterval(function () {
//create an ajax call
}, 30000);
});
but it's not the point - I can't find any information of the other approaches. Is it the only way to achieve this by set the setInterval function to check the updates ?
Edit
Ok, I've found http://socket.io/ maybe it's what I'm looking for
You could as well use setTimeout on callback, so that every time something comes back from the server it will set another timer for like 30 sec later. There are advantages of this (server won't be overloaded with your requests even if the response is slow) but also drawbacks (once there's no answer poll won't run again).
Also there are other ways of keeping an eye on the server; search for the term "long polling" in Google.
This is the easiest solution. Otherwise you should use sockets like http://socket.io which is more low level but in this way you could implement push messages to the client.
Here is a tutorial of a nodejs and socket.io push notification server: http://www.gianlucaguarini.com/blog/nodejs-and-a-simple-push-notification-server/
And this is another one for PHP:
http://pusher.com/tutorials/html5_realtime_push_notifications

A Reliable timer for Javascript

I have a web site and i am using a javscript timer to swap images about.
I am using the timer like this:
var myTimer = window.setTimeout(MyFunction, MyInterval);
function MyFunction
{
//do something
//recalll timer
}
Now, the problem I have is not that the interval does not fire off at regular intervals as I can accept that in my application and I understand why it can vary.
The issue I have is that every now and then the timer stops for a few seconds and then resumes.
What I am trying ascertain is what is the main cause of this random suspension of the timer?
Is it due to the resources being diverted to another process on the hosting browser PC OR is it just the nature of using a JavaScript timer?
If the latter should I look to do an eternal loop? Everywhere I read and have practised elsewhere indicates that an infinite loop will grab all the resources and it would be a greater evil than the timer random suspension.
Are there any alternatives to using a javascript timer when a regular quick execution of code is paramount?
Thanks
The code you run inside MyFunction takes some time to execute (depending on what you are doing). When you recall the timer at the end of that function, the interval is not exactly MyInterval, because of the code execution time being added.
If you use setInterval() instead of setTimeout(), the given function will be executed exactly every MyInterval milliseconds rather than (MyInterval + execution time) milliseconds.
To answer your question, the random suspension happens because of the execution time of your code.
I had a similar issue on a website I was working on and ultimately found the culprit in another timer-triggered job in a jQuery plugin that was occasionally delaying execution of my own function. If you're using external code in your site, you could do some debugging to see if this is your case too.
As a possible remedy, you could give a look at web workers. Since worker tasks are executed in a separated thread, they are not subject to delay when something in your main thread is taking too long to complete.
Your code would then look like this:
var worker = new Worker('worker.js');
And in another file called "worker.js" you would write:
var myTimer = setTimeout(MyFunction, MyInterval);
function MyFunction
{
//do something
//recalll timer
}
Just note that there is no window. anymore before setTimeout. This is because web workers don't have direct access to the DOM.
It's not guaranteed to solve your problem, but it's worth a test.

Can JavaScript's setInterval block thread execution?

Can setInterval result in other scripts in the page blocking?
I'm working on a project to convert a Gmail related bookmarklet into a Google Chrome extension. The bookmarklet uses the gmail greasemonkey API to interact with the gmail page. The JavaScript object for the API is one of the last parts of the Gmail page to load and is loaded into the page via XMLHttpRequest. Since I need access to this object, and global JavaScript variables are hidden from extension content scripts, I inject a script into the gmail page that polls for the variable's definition and then accesses it. I'm doing the polling using the setInterval function. This works about 80% of the time. The rest of the time the polling function keeps polling until reaching a limit I set and the greasemonkey API object is never defined in the page.
Injected script sample:
var attemptCount = 0;
var attemptLoad = function(callback) {
if (typeof(gmonkey) != "undefined"){
clearInterval(intervalId); // unregister this function for interval execution.
gmonkey.load('1.0', function (gmail) {
self.gmail = gmail;
if (callback) { callback(); }
});
}
else {
attemptCount ++;
console.log("Gmonkey not yet loaded: " + attemptCount );
if (attemptCount > 30) {
console.log("Could not fing Gmonkey in the gmail page after thirty seconds. Aborting");
clearInterval(intervalId); // unregister this function for interval execution.
};
}
};
var intervalId = setInterval(function(){attemptLoad(callback);}, 1000);
Javascript is single threaded (except for web workers which we aren't talking about here). That means that as long as the regular javascript thread of execution is running, your setInterval() timer will not run until the regular javascript thread of execution is done.
Likewise, if your setInterval() handler is executing, no other javascript event handlers will fire until your setInterval() handler finishes executing it's current invocation.
So, as long as your setInterval() handler doesn't get stuck and run forever, it won't block other things from eventually running. It might delay them slightly, but they will still run as soon as the current setInterval() thread finishes.
Internally, the javascript engine uses a queue. When something wants to run (like an event handler or a setInterval() callback) and something is already running, it inserts an event into the queue. When the current javascript thread finishes execution, the JS engine checks the event queue and if there's something there, it picks the oldest event there and calls its event handler.
Here are a few other references on how the Javascript event system works:
How does JavaScript handle AJAX responses in the background?
Are calls to Javascript methods thread-safe or synchronized?
Do I need to be concerned with race conditions with asynchronous Javascript?
setInterval and setTimeout are "polite", in that they don't fire when you think they would -- they fire any time the thread is clear, after the point you specify.
As such, the act of scheduling something won't stop something else from running -- it just sets itself to run at the end of the current queue, or at the end of the specified time (whichever is longer).
Two important caveats:
The first would be that setTimeout/setInterval have browser-specific minimums. Frequently, they're around 15ms. So if you request something every 1ms, the browser will actually schedule them to be every browser_min_ms (not a real variable) apart.
The second is that with setInterval, if the script in the callback takes LONGER than the interval, you can run into a trainwreck where the browser will keep queuing up a backlog of intervals.
function doExpensiveOperation () {
var i = 0, l = 20000000;
for (; i < l; i++) {
doDOMStuffTheWrongWay(i);
}
}
setInterval(doExpensiveOperation, 10);
BadTimes+=1;
But for your code specifically, there's nothing inherently wrong with what you're doing.
Like I said, setInterval won't abort anything else from happening, it'll just inject itself into the next available slot.
I would probably recommend that you use setTimeout, for general-purpose stuff, but you're still doing a good job of keeping tabs of the interval and keeping it spaced out.
There may be something else going on, elsewhere in the code -- either in Google's delivery, or in your collection.

Improving long-polling Ajax performance

I'm writing a webapp (Firefox-compatible only) which uses long polling (via jQuery's ajax abilities) to send more-or-less constant updates from the server to the client. I'm concerned about the effects of leaving this running for long periods of time, say, all day or overnight. The basic code skeleton is this:
function processResults(xml)
{
// do stuff with the xml from the server
}
function fetch()
{
setTimeout(function ()
{
$.ajax({
type: 'GET',
url: 'foo/bar/baz',
dataType: 'xml',
success: function (xml)
{
processResults(xml);
fetch();
},
error: function (xhr, type, exception)
{
if (xhr.status === 0)
{
console.log('XMLHttpRequest cancelled');
}
else
{
console.debug(xhr);
fetch();
}
}
});
}, 500);
}
(The half-second "sleep" is so that the client doesn't hammer the server if the updates are coming back to the client quickly - which they usually are.)
After leaving this running overnight, it tends to make Firefox crawl. I'd been thinking that this could be partially caused by a large stack depth since I've basically written an infinitely recursive function. However, if I use Firebug and throw a breakpoint into fetch, it looks like this is not the case. The stack that Firebug shows me is only about 4 or 5 frames deep, even after an hour.
One of the solutions I'm considering is changing my recursive function to an iterative one, but I can't figure out how I would insert the delay in between Ajax requests without spinning. I've looked at the JS 1.7 "yield" keyword but I can't quite wrap my head around it, to figure out if it's what I need here.
Is the best solution just to do a hard refresh on the page periodically, say, once every hour? Is there a better/leaner long-polling design pattern that won't put a hurt on the browser even after running for 8 or 12 hours? Or should I just skip the long polling altogether and use a different "constant update" pattern since I usually know how frequently the server will have a response for me?
It's also possible that it's FireBug. You're console.logging stuff, which means you probably have a network monitor tab open, etc, which means every request is stored in memory.
Try disabling it, see if that helps.
I suspect that memory is leaking from processResults().
I have been using very similar code to yours in a long-polling web application, which is able to run uninterrupted for weeks without a page refresh.
Your stack should not be deep, because fetch() returns immediately. You do not have an infinitely recursive loop.
You may want to use the Firefox Leak Monitor Add-on to assist you in finding memory leaks.
The stack depth of 4-5 is correct. setTimeout and $.ajax are asynchronous calls, which return immediately. The callback is later called by the browser with an empty call stack. Since you cannot implement long polling in a synchronous way, you must use this recursive approach. There is no way to make it iterative.
I suspect the reason for this slow down is that your code has a memory leak. The leak could either be in $.ajax by jQuery (very unlikely) or in your processResults call.
It is a bad idea to call fetch() from inside the method itself. Recursivity is better used when you expect that at some point the method will reach an end and the results will start to be send to the caller. The thing is, when you call the method recursively it keeps the caller method open and using memory. If you are only 3-4 frames deep, it is because jQuery or the browser are somehow "fixing" what you've done.
Recent releases of jquery support long-polling by default. This way you can be sure that yhou are not deppending on browser's intelligence to deal with your infinite recursive call. When calling the $.ajax() method you could use the code below to do a long poll combined with a safe wait of 500 miliseconds before a new call.
function myLongPoll(){
setTimeout(function(){
$.ajax({
type:'POST',
dataType: 'JSON',
url: 'http://my.domain.com/action',
data: {},
cache: false,
success:function(data){
//do something with the result
},
complete: myLongPoll,
async : false,
timeout: 5000
});
//Doesn't matter how long it took the ajax call, 1 milisec or
//5 seconds (timeout), the next call will only happen after 2 seconds
}, 2000);
This way you can be sure that the $.ajax() call is closed before the next one starts. This can be proved by adding a simple console.log() at the prior and another after your $.ajax() call.

javascript parallelism

Well, first I want to say I'm a bit new in the world of Internet dev.
Anyway, I'm trying to know if its possible to run two pieces of code in parallel using javascript.
What I really need is to call two methods that are in a remote server. I pass, for both, a callback function that will be executed soon the data I want is ready. As the server running these functions take a time to answer, I'm trying to find a way to call both methods at the same time without need to wait till the first finishes to call the second.
Does methods like setTimeout run concurrently, for example
setTimeout(func1, 0);
setTimeout(func2, 0);
...
function func1()
{
webMethod1(function() {alert("function 1 returned"); } );
}
function func1()
{
webMethod2(function() {alert("function 2 returned"); } );
}
Edited
I've just found this article that may be very cool for the realease of next browsers: Javascript web workers
There is one single thread of execution in Javascript in normal WebBrowsers: your timer handlers will be called serially. Your approach using timers will work in the case you present.
There is a nice piece of documentation on timers by John Resig (author of the very popular jQuery javascript framework - if you are new to Web development, I would suggest you look it up).
Now, if you are referring to HTML5 based browsers, at some point, they should have threading support.
Yes, that's exactly how web requests through AJAX work. No need to setTimeout to 0, you can just call them one by one, and make an AJAX request, and it'll be executed asynchronously, allowing you to pass a callback function to be invoked when the request completes.
The means of creating an AJAX request differs some depending on what browser you're running. If you're going to build something that depends considerably upon AJAX, and you want it to work across multiple browsers, you're best off with a library. Here's how it's done in jQuery, for instance:
$.ajax({ url: '/webrequesturl', success: function(result) {
// this will be called upon a successful request
} });
$.ajax({ url: '/webrequest2url', success: function(result) {
// this will be called upon a successful request
// this may or may not be called before the above one, depending on how long it takes for the requests to finish.
} });
Well, JavaScript is single-threaded, the two timers will run sequentially one after the other, even if you don't notice it.
I would recommend you to give a look to the following article, it really explains how timers and asynchronous events work, it will also help you to understand the single-threaded nature of JavaScript:
How JavaScript Timers Work
And as an alternative you could give a look to WebWorkers, is a way to run scripts in separate background threads, but they are only supported by modern browsers.
What you are looking for is asynchronous client-server communication (keyword: async). Asynchronous functions return straight away, but the provided callback will be executed after the specified condition is satisfied.
So, if the function that sends a request to the server is asynchronous, this would let you send both requests to the server without waiting for one to respond.
Using setTimeout may work, as this will schedule both request-sending functions to be called. However, some browsers only run one thread of Javascript at a time, so the result would be that one of the scheduled functions would run and block (waiting for a reply) and the other scheduled function would wait until the first was done to start running.
It is advisable to use async support from your server communication library. For instance jQuery uses async by default.
It depends on the JavaScript engine.

Categories