I want to build an application which will automatically broadcast notification(s) to a user when data on server is changed. So far, I just know one method of doing this i.e. using JQuery setInterval. Using this function, every client requests data through ajax to server, asking if something changed.
The weakness of this method is every client must send a packet every specific time interval, so my server receives huge data packet. It's so frustrating to manage the server. Are there any alternatives for this besides Jquery setInterval?
If Websockets is not an option for you, you could use one ajax request to the server. Than server side go into a infinite loop. Use the sleep function to not overload the memory. Than check each time if there is something changed. If so, break out the loop and return the data. On the client side send immediately the next request.
After a bit of research it's called "Ajax long-polling requests".
Here is a explanation.
The PHP code would look something like this:
$prevHash = $_GET['hash'];
while(true){
$currHash = GetHashFromTable('myTable');
if ($prevHash != $currRowCount) break;
sleep(3);
}
$response[0] = GetDataFromTable('myTable');
$response[1] = GetHashFromTable('myTable');
echo json_encode($response);
Update
Long polling is not the best option. Better to use web-sockets.
If you want to compare the differences, see this answer: https://stackoverflow.com/a/10029326/3269816
Related
I am trying to write a plugin which will work a lot with my server. Every page load will invoke an AJAX call to my server for data, the server should return a simple string.
Now I am trying to understand what would be the best aproach for this type of program.
Should I just create an AJAX call every time I need the data or is there some method I could create an open connection (despite the change of webpages) to save on server power?
Should I somehow listen to some port or something of the sort?
Do I have other options or what should I do to do this the most efficient way?
You can use HTML5 websockets (http://www.html5rocks.com/en/tutorials/websockets/basics/)
If you use this approach, then you will need to re-think the way you program your webserver, since websockets don't follow the request-response paradigm AJAX do. Instead they use a connection to stream data so you will need to open a port on your server and listen to it, the way to do it depends on the language or framework you are using. This is fast and responsive but will only work on most modern browsers.
Other approach is using Long Polling (http://techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery). This is used by some chat clients. It works sending an AJAX request to the server, the server receives it and keeps it waiting until the data is available and then the response is sent. Then the client makes another request, waits and repeats.
Probably you will almost never want to send simple strings to the client. It's almost always better to use XML or JSON to encode the response.
Just create a simple AJAX call and put it on each page, or save it as it's own file and put a server include on each page in the header. Simple as that!
$(document).load(function(){
$.ajax({
type: "POST",
url: "/where_your_string_is.php",
success: function(msg){
$("#stringHolder").html(msg);
}
});
});
Websockets API allows bi-directional communication, but I've just found that there's another option called HTML SSE that might be used if you only need to pull data. So if you've stumbled upon this question, consider this option as well.
The more I work with AJAX the more I find myself faced with the same problem: I want data on the screen to be as up to date as possible but downloading the same data every second is over kill. The data may change only once every 30 minutes but when it does I would like this to be fed back to the user instantly.
Getting my server side scripts to return data describing the difference between the previous data can be a nice solution but is not always a possibility.
Is there a neat solution to this or is this just something I'm going to have to live with?
Nodejs and Socket.io. It works totally different. In your solution each opened window sends a request to the server, and as a result there is a very huge amount of useless request. Nodejs with Sokcet.io is a real PUSH engine. You can connect users by sockets, and push them notify, that the page should refresh, or updated data itself.
Nodejs and Socket.io links.
you have to query the server every time, that's a given. what you can do is test, in the server, if there is any new data to update and, if not, just return something like 'false', so the callback doesn't do anything and less data is passed around each time.
You're looking for a comet or long-polling technique. Here is a general description with a nice explanation: http://www.ibm.com/developerworks/web/library/wa-reverseajax4/?ca=drs-
Also, the cometd website, which will work with jquery or dojo: http://cometd.org/
I
Another solution is Atmosphere: https://github.com/Atmosphere/atmosphere
Also here: http://jfarcand.wordpress.com/2010/06/15/using-atmospheres-jquery-plug-in-to-build-applicationsupporting-both-websocket-and-comet/
Let's imagine the situation that we've sent two similar (almost similar) async ajax requests to server one by one. Because of lag in network, the second request was executed before first request.
Ajax request #1: /change/?object_id=1&position=5
Ajax request #2: /change/?object_id=1&position=6
In result, we have object_id=1 position set to position=5, but we want position=6 because Ajax request #2 was executed after Ajax request #1 by us.
What is the best practice to avoid this on server side and client side?
Are you worried about racing conditions from the same client or from multiple clients?
If from the same client, I would think the safest bet would be to include a unix timestamp in the ajax request and log this value on the server. If a request comes with a timestamp that is older than the last logged value, ignore the request (or send a warning back to the browser).
I'm not sure how you would handle multiple clients with unsynchronized clocks...
For situations like this, I usually put a check in my success handler to make sure that the value being returned is still the one that I want. This will require sending up the parameter you're searching across in the results object.
For example:
var query = $('input').val();
$.get('/search', { query: query }, function(res) {
if(res.query == $('input').val()) {
//show search results
}
});
I don't know the particulars of your use case, but this general pattern should help.
On the server :
Build a request table to map request id to timestamp
Log any request to the server, expect all requests come with timestamp
If any request comes out of order (e.g. position 6 comes before 5)
Check the request table, if it is an earlier request (timestamp) then do not process the request and send an ignore flag
If it comes in order
This is fine, proceed as usual and no need to send any ignore order
On the client:
When request comes back in, check the ignore flag. If it is there. Don't do anything to the client
Otherwise proceed as usual by processing the data
Note that this implementation that I suggested requires you to send back and forth data (such as JSON) and not the presentation code (such as HTML fragment) as you would need to check for the ignore flag on the client side.
This answer is similar to what #Farray suggestion of using timestamp.
Hello guys i want to process some server pushes. I have an asynchronous servlet processing something, pushing it to the client and then it processes something else and pushes it again to the client (same connection). The servet just returns data (Json in this case, but that does not really mather) nothing more.
So my problem is the client. How do i build a client for that? If i make an ajax request with JQuery for example how can i react on the data that comes after the first response?
To make it more clear what i want here is a comparison : With websockets i have the method onmesssage.
websocket ws = new WebSocket("ws://myserver.com");
ws.onmessage = function(event)
{
var x = event.data
.... // some other code here
}
So all i want is a onmessage Method :). I guess it is not that easy as it is with websockets but maybe someone has an idea.
Greetings Aleks
You can have your server generate a response which is loaded into an hidden iframe by the client. The generated response would contain occasional JavaScript statements which call to the "outside" (the containing document). You can get your hands on the containing document using parent.
But please not that this technique is pretty hackish (at least it seems to me). You might want to re-consider just using the XMLHttpRequest, especially because it gives you simple and robust error handling. You can just do more requests (instead of appending to an "old" response on the server side). This will probably introduce additional lag, but that iframe trick is really troublesome in practice.
I am trying to develop an Interactive chat application using AppWeb open source web Server.
I need to have some machanism that will enable Web server to send updated messages to client, so that when remote usre sends messages that will get updated automaticaly at the client end.
There are some methods to do this using HTML5 Web Sockets and Server sent events.
But we need to implement it in HTML and JavaScript only not HTML5.
So I need some pooling machanism that will keep pooling my Web Server for New events.
So how should I write pooling machanism in Javascript using Sockets.
How it should be implemented at server end?
Thanks!
there are already some examples out there... depending on the server-side, you could go for java-hello-world or php-hello-world or ...
if you can't use websocket, you have to can go the old way, create an interval by window.setInterval and pull data from the server with eg. $.ajax(). i don't know any other alternative to bidirectional connection (websocket)... see kayahrs answer
as you've asked for it:
$.ajax() is the jQuery way to do xhr. basically, it fires an asynchronous request to the server, which returns xml or json or text or ... (whatever). when this request comes back, the supported eventHandler gets fired and you can react to the response. you could also use the plain xhr, but it's a bit awkward to handle the original xhr.
jQuery supports some shorthand overloads for $.ajax(), eg. $.getJSON(), $.get(), ...
sample implementation:
$.get("test.cgi", function(data){
alert("Data Loaded: " + data);
});
There is another technique for sending messages from the server to the client. You have to use an iframe for this which connects to a PHP script (Or whatever technique you are using on the server side) which does not close the connection. The PHP script then sends JavaScript messages whenever the client must be informed about something. After each message the server flushes the output stream to enforce that the data really finds its way to the client and is not cached by some output buffer. Here is a small example code of the PHP script loaded in the iframe (not tested and not complete, just to show the basics):
<html>
<body>
<script type="text/javascript">
function receiveMsg(data)
{
// Do something with the data, for example send it to some function
// in the parent frame (Where your chat application lives)
}
<?php
while (true) // You may also implement some abort state which should
// be checked here
{
$data = waitForData(); // This is your magic function on the server
// which waits for data to be send to the client
echo "receiveMsg('" . $data . "');"; // Let's say data is just a string.
// You may want to use JSON instead
flush();
}
?>
</script>
</body>
</html>
Advantage of this method is that it doesn't rely on polling. So you don't have to send requests to the server every x seconds. And when you do things right on the server side then messages sent by one user are received as fast as possible by the other users and not x seconds later. Disadvantage is that you have a permanent HTTP connection for each chat user. But this may need less resources on the server then having dozens of complete HTTP requests per minute per chat user.