I am writing a simple chat-client (completely intended for learning purposes). My android phone sends messages to a remote MySQL database, and I am in the process of getting the browser to display any new incoming messages.
My current approach is using javascript: it calls a function every 5 seconds, which in turn calls a php that queries for new messages and sends it back to the browser.
I have no experience in ajax, but I've heard it is good when data has to change in a webpage constantly without having to refresh the page, which fits my situation.
My question is, does this sound like something I should use ajax for?
Yes, ajax is the way to go. However, what you have suggested (checking for messages every 5 seconds) generates a lot of requests and bandwidth. You should look into comet, which is still ajax but uses it in a different way.
Comet essentially is this:The client sends a request to the server. The php file on the server has a loop checking every few seconds for a message. When the server finds a message, it echos the message, but it doesn't close the connection. When another message arrives, it echos it again, but doesn't close the connection. This allows it to only need 1 request instead of hundreds. See http://www.zeitoun.net/articles/comet_and_php/start
I'll advice you to go for either ajax or websockets... if you're going for websocket, learn node.js... it has a lot of cool feature as platform built on Google Javascript V8 engine
Related
I am starting a long polling request for every page of my website. It looks every second at the database and if there is something new it marks it as seen and outputs the notification. The calling JavaScript is then starting a new ajax request.
Now I got problems having opened multiple tabs on the website, because only one will recieve a new notification. This is also a problem cross-browser with the same username logged in...
What would be the smartest way to solve this fool-proof?
Than you for your input!
I think it is better to avoid browser pulling. You will have browsers problems and also your infrastructure should be huge to support it.
Try a server side pushing tech like Commet,
Comet is a web application model in which a long-held HTTP request
allows a web server to push data to a browser, without the browser
explicitly requesting it.
Other approach could be using WebSockets.
I currently have an IRC bot written in C++ which monitors a page written in php for changes and then outputs these changes to the IRC channel.
However the current method is rather in-effective as it just constantly polls the page once every 10 seconds and compares it to the last seen version to check if anything has changed.
I can decrease the page check interval to about 2-3 seconds before the IRC bot starts to take a performance hit, however this isn't ideal.
Often the page I am monitoring can change multiple times within the 10 second period, so a change could be missed, what would be a better method to get the data from the page? considering I control both the page written in PHP, and the IRC bot, but they are on different servers.
The sole purpose of this page is to pass data to the IRC bot, so it could be completely re-implemented as something else if that would be a better solution; the IRC bot also monitors multiple versions of this page to check for different things.
If the data generated by PHP isn't somehow pushed on a stream (broadcast or feed), you don't have any other choice than polling the page, unfortunately.
What you could do is push the data from PHP using broadcast, or make a persistent connection from the bot to the PHP script, or make the PHP calculate the differences itself.
The PHP script should send a message to a public port or path that your IRB bot listens on, containing information about any posts made. This way, you are notified only when a message arrives.
One note about doing these sorts of things, beware if there are a lot of posts within a short period; if concurrency is important, you'll want to implement this using a proper MQ service like 0MQ/RabbitMQ/InsertMQFrameworkNameHere to ensure the messages arrive in order and are guaranteed sending and receiving.
If you need to monitor every change, then have your PHP page "push" data to your bot rather than your IRC bot "pull" data from the page (through polling). This can be done over any network socket, even something like a HTTP POST request from your PHP page to your bot over port 80.
A good alternative to polling is Comet. Here are examples (for JavaScript though): http://www.zeitoun.net/articles/comet_and_php/start.
I would suggest this approach:
when you retrieve your page, specify a very long timeout, say 10 minutes (bear with me for a moment);
if you have a new page, let the server return it; otherwise just don't send a reply
if there is no page, the client will wait for up to 10 minutes before giving up (timing out); but, if during this time a new page is there, your server can reply to the request and pass the page to the client;
in case the timeout fires, you simply send another request with the same long timeout.
Hope I could explain it clearly. The only tricky point is how your web page (PHP) can hold the wait when a request arrives if there is no new data to send back.
This can be easily accomplished like this:
if ($newDataAvailable) {
file_put_contents($data, $request_uri);
return;
}
while (!$newDataAvailable) {
usleep(10000);
$newDataAvailable = <check_for_data>;
}
//-- here data is available
<build response using get_file_contents($uri)>
<send response>
When I am using gmail, some new mails that I just received appear on the inbox, even if I did not refresh the page. I believe that would done in Ajax.
Is there any good demo that works very similar to it? Periodically checking and getting JSON data (I am not sure if it is JSON data..) to fetch new data??
Thanks!
The problem with periodic refresh is that while it is good for some things that aren't too time critical, like e-mail fetching, it is not instantaneous. Therefore you wouldn't want to use it for something like chat where waiting even five seconds for a response is too long. You could decrease the polling interval and make a request once a second or even half second, but then you'd quickly overload your browser and waste resources.
One solution for this is to use a technique called ajax long polling (known by others as 'comet' or 'reverse ajax'). With this technique, the browser makes a long duration ajax request, one that does not return until there is new data available. That request sits on the server (you need to be running special server side software to handle this in a scalable manner, but you could hack something together with php as a demonstration) until new data is available at which point it returns to the client with the new data. When the client receives the data it makes another long polling request to sit at the server until there is more data. This is the method that gmail uses, I believe.
That is the gist of long polling, you have to make a couple of modifications because most browsers will expire an ajax request if it does not return after a long time, so if the ajax request times out the client has to make another request (but the timeout is usually on the interval of a minute or longer). But this is the main idea.
The server side implementation of this is far more complicated than the client side (client side requires just a few lines of js).
While I'm not sure of the exact gmail implemention, the AjaxPatterns site has a good overview of what they dub a Periodic Refresh: --> http://ajaxpatterns.org/Periodic_Refresh. I've always just referred to the style as a heartbeat.
The gist of their solution is:
The browser periodically issues an XMLHttpRequest Call to gain new information, e.g. one call every five seconds. The solution makes use of the browser's Event Scheduling capabilities to provide a means of keeping the user informed of latest changes.
They include some links to real-world examples and some sample code.
I'm trying to find some php and jquery tutorial/plugin or piece of code which enables to get the real time notifications. For example, if some data is inserted in the database, i want to receive the notification on the webpage in real time without refresh etc. If you know any resource, please let me know. Bundle of thanks.
You will need to poll the server, preferably using long polling (not trivial with PHP).
The server can respond blank, or a JSON message if there is something to be returned.
here is periodic updater built as a jQuery plugin that tries to implement long polling and reduce the load on the server.
https://github.com/RobertFischer/JQuery-PeriodicalUpdater/
What way will be best to write online chat with js? If i would use AJAX and update information about users and messages every 5sec - HTTP requests and answers will make big traffic and requests will make high server load.
But how another? Sockets? But how..
You seem to have a problem with the server load, so I'll compare the relevant technologies.
Ajax polling:
This is the most straightforward. You do setTimeout loop every 5 seconds or so often to check for new chat messages or you set an iframe to reload. When you post a message, you also return new messages, and things shouldn't get out of order. The biggest drawback with this method is that you're unlikely to poll with a frequency corresponding to how often messages are posted. Either you'll poll too quickly, and you'll make a lot of extra requests, or you'll poll too slowly and you'll get chunks of messages at a time instead of getting them in a real-time-ish way. This is by far the easiest method though.
HTTP Push
This is the idea that the server should tell the client when there are new messages, rather than the client continually bothering the server asking if there are any new ones yet. Imagine the parent driving and kid asking "are we there yet?", you can just have the parent tell the kid when they get there.
There are a couple ways to both fake this and do it for real. WebSockets, which you mentioned, are actually creating a stream between the client and the server and sending data in real time. This is awesome, and for the 4 out of 10 users that have a browser that can do it, they'll be pretty psyched. Everyone else will have a broken page. Sorry. Maybe in a couple years.
You can also fake push tech with things like long-polling. The idea is that you ask the server if there are any new messages, and the server doesn't answer until a new message has appeared or some preset limit (30 seconds or so) has been reached. This keeps the number of requests to a minimum, while using known web technologies, so most browsers will work with it. You'll have a high connection concurrency, but they really aren't doing anything, so it should have too high a server cost.
I've used all of these before, but ended up going with long polling myself. You can find out more about how to actually do it here: How do I implement basic "Long Polling"?
You should chose sockets rather than AJAX Polling, However there isn't much around about how you can integrate socket based chats with MySQL.
I have done a few tests and have a basic example working here: https://github.com/andrefigueira/PHP-MySQL-Sockets-Chat
It makes use of Ratchet (http://socketo.me/) for the creation of the chat server in PHP.
And you can send chat messages to the DB by sending the server JSON with the information of who is chatting, (if of course you have user sessions)
There are a few ways that give the messages to the client immediately:
HTML5 Websockets
good because you can use them like real sockets
bad because only a few browsers support it
Endlessly-loading frame
good because every browser supports it
not so cool because you have to do AJAX requests for sending stuff
you can send commands to the client by embedding <script> tags in the content
the script gets executed immediately, too!
...
So, in conclusion, I would choose the second way.
The typical approach is to use long polling. Though better not do this in PHP (PHP will need one process for each connection thus drastically limiting the number of possible visitors to your site). Instead use node.js. It's perfect for chats.