How can I write a real time chat using XAJAX and PHP?
In other words, is there a way to send xajax responses from the server to multiple clients?
Or is the only possibility to check for new messages every few seconds on client side?
No. Clients must "poll" the server repeatadly.
I think the key here is to think interaction design. The trick is to fool the user into thinking that the chat is instant, but when in reality it updates once every 1 or 2 or 3 or 10 seconds.
Ideas:
1) When the user sends a message, show it directly in the chat and trigger a poll.
2) If a poll comes back with multiple messages from other users, don't add them all at once, actually add them over a period of 1-2 sec or so, with random spacing, making it look like they're coming in "instantly" and independently. (If a bunch of messages come in at once the user is very quick to realize that the chat updated there and then, and not continiously.)
3) If the user is idle for x amount of time. Drop the poll rate to once every 10sec or so.
4) If the user is active, ie sending a lot of messages, poll more often.
5) Have a static file for every channel that your write the time the chat last updated to. For instance file chat-teenfun-lastupdate.txt has the contents 1224934239 or whatever time format you prefer. Serve this file statically and let clients poll this file in order to check if the channel has updated, rather that calling chat-poll.php?ch=teenfun that does a dynamic check. Static files are served around 10-100 times faster, depending on the work involved for the dynamic script, and you're gonna need it when you get 250+ users polling.
Good luck and have fun!
/0
PS. Alternatively you could actually let clients do an ajax call to the server and keep them 'hanging'. That is you accept their request and pretend to start sending data back, but then you just pause. When something happends you finish the response with the approriate data. For this to work I believe you'd need to write your own HTTP-server though, that does this specifically, as you can't have 250 php processes hanging around in memory. Maybe Lighttpd could be used in this way somehow with that LUA cache mod. I don't know. Would be interesting though. Hell I gotta try it sometime :)
Sure there is, but I don't think it'll be very efficient with many users. You can either do polling where each client polls the server to see if there are any new messages, or you could use the comet technique in which the server can push new messages to the clients - Check out the Comet plugin for XAJAX. How this would be implemented using XAJAX and PHP is beyond me, but here's how I would try to implement it.
Let each client connect to the server (login etc), then:
For each message sent by a client (sender) update the message queue for client (receiver)
Let client poll server for new messages in the queue / Push the new messages via comet.
Update GUI if there are new messages.
Rinse, lather, repeat
Using a true IM server like ejabberd could go a long way, be more efficient and allow your users to connect via desktop clients (if that's what you want). I'd probably use that as a backend, IOW ejabberd would be the server and PHP would be the client using XMPP in PHP, and act as a proxy for the webgui.
See also:
Google Techtalk on Gmail's chat feature (and scalability issues)
That's my $0.02
As long as there there is not HTTP push technology you will never get a realtime chat only using JavaScript.
Possible workarrounds:
use a Flash Movie or a Java Applet to perform some socket communication
hold polling requests back on the server side for a few seconds
You could use websockets, but being a new HTML5 feature it's kinda limited. Lucky for you there is socksjs, which implements websockets on browsers that do not handle it.
On the hosting side you should be able to use any websockets server, there's a few for PHP.
If you are looking to implement a chat server written with a scripting language such as PHP/JSP, technique of hanging HTTP connection will have to be ticked off from your your options list. The reason is most of the web severs (specially shared hosts) don't like too many connections hanging.
You can find everything you need to implement a web client and PHP chat server in this "Optimized Chat Server Protocol for Server Side Scripting Languages" publication.
The best strategy I've seen is to do an AJAX request for messages and then restart that exact same request as soon as it finishes.
On the server side, make the script "stall" for 60 seconds or until a new message is received. This keeps the same connection open for a max of 60 seconds, but when a new message is received, it outputs it and stops immediately, prompting the client-side AJAX to open another connection.
This provides almost instant notification of new messages and is also much easier on the server than making a new connection every x seconds.
Related
I've been reading a lot on the subject of SSE and PHP, most of which seems to be advocating it as viable solutions for all sorts of things including chat apps. I have seen similar questions on this site but have not found a concise, definitive answer.
Is there something inherent in SSE which makes it way more server-friendly than AJAX short polling? Because the headers appear to be of very similar size. I am wondering if there is some kind of behind-the-scenes stuff beyond the headers that a noob like myself can't see e.g. some sort of connection recognition with each request/response? I know there are other factors involved where SSE prevails such as handling disconnections.
In terms of using it in a chat app scenario, ajax and sse appear to be doing the same thing. Neither of them seems to be able to perform long polling effectively with PHP. If I have User A and User B waiting on a PHP script that checks for new messages from the other user in the DB then sleeps for 3 seconds for say 10 loops, User A's new message cannot be inserted until User B has looped through the entire checking script, thereby rendering it absolutely useless (at least based on everything I've tried in the last 2 weeks!). I can get it working smoothly if I chat to myself and no one else is waiting on the checking script, but I've run out of things to talk about with myself and would really enjoy someone else being able to use it too.
So in a nutshell, given an Apache and PHP environment with WebSockets as not an option (due to shared hosting), is the only effective way to write a chat app, based on server burden alone, by short polling with one's choice of either AJAX or SSE, or is SSE definitely the superior option?
I would pursue WebSockets if the eventual traffic called for it and justified the web hosting upgrade.
(ALSO, as a side, is my premise off base regarding the long-polling scenario I described above where User A must wait for User B's loop to finish before he/she/it can perform the insert? Got me confused as to why that should be the case).
Kind of a long-winded, meandering question but hoping someone in the same situation can find this question and save themselves a lot of time.
Many Thanks!
Yes, SSE is a better option than AJAX, as AJAX polling is done on the main servers, like where most of the normal user traffic is to be hit. Whereas SSE polling is done on another instance which is made for it, so there will be no extra traffic on the main server. Please check Mercure (https://mercure.rocks/)
EDIT:
I mean to that, using SSE with platforms like Mercure would be a better option than AJAX. As AJAX will make a request to the main server. Which would increase the count of requests for the main server. Whereas we can distribute the network load using tools like the Mercure, in order to achieve the required functionality.
SSE can be thought of a thin API wrapper around the AJAX long-poll approach. It brings a standard API to something that was a hacky solution before.
something inherent in SSE which makes it way more server-friendly than AJAX short polling?
It holds the socket open. The pro of this is less latency (as soon as the server has the new information it sends it to the client, rather than waiting for the next client poll); the con is the extra resource usage (the socket, and the PHP process).
but I've run out of things to talk about with myself
Surely not. Have you tried starting a chat about if time is an illusion, and what came before?
with WebSockets as not an option (due to shared hosting)
SSE and WebSockets both hold a socket open. Shared hosting ISPs often go round closing sockets that have been open a long time (e.g. over 60s), unless they explicitly say they support SSE. The may also kill long-running PHP processes.
is my premise off base regarding the long-polling scenario I described above where User A must wait for User B's loop to finish before he/she/it can perform the insert?
I think it is off. The "A" in Ajax is asynchronous, meaning you can have multiple ajax/sse requests running at the same time. And on the server side you will have a distinct PHP process running for each request.
So a friend and I are building a web based, AJAX chat software with a jQuery and PHP core. Up to now, we've been using the standard procedure of calling the sever every two seconds or so looking for updates. However I've come to dislike this method as it's not fast, nor is it "cost effective" in that there are tons of requests going back and forth from the server, even if no data is returned.
One of our project supporters recommended we look into a technique known as COMET, or more specifically, Long Polling. However after reading about it in different articles and blog posts, I've found that it isn't all that practical when used with Apache servers. It seems that most people just say "It isn't a good idea", but don't give much in the way of specifics in the way of how many requests can Apache handle at one time.
The whole purpose of PureChat is to provide people with a chat that looks great, goes fast, and works on most servers. As such, I'm assuming that about 96% of our users will being using Apache, and not Lighttpd or Nginx, which are supposedly more suited for long polling.
Getting to the Point:
In your opinion, is it better to continue using setInterval and repeatedly request new data? Or is it better to go with Long Polling, despite the fact that most users will be using Apache? Also, it possible to get a more specific rundown on approximately how many people can be using the chat before an Apache server rolls over and dies?
As Andrew stated, a socket connection is the ultimate solution for asynchronous communication with a server, although only the most cutting edge browsers support WebSockets at this point. socket.io is an open source API you can use which will initiate a WebSocket connection if the browser supports it, but will fall back to a Flash alternative if the browser does not support it. This would be transparent to the coder using the API however.
Socket connections basically keep open communication between the browser and the server so that each can send messages to each other at any time. The socket server daemon would keep a list of connected subscribers, and when it receives a message from one of the subscribers, it can immediately send this message back out to all of the subscribers.
For socket connections however, you need a socket server daemon running full time on your server. While this can be done with command line PHP (no Apache needed), it is better suited for something like node.js, a non-blocking server-side JavaScript api.
node.js would also be better for what you are talking about, long polling. Basically node.js is event driven and single threaded. This means you can keep many connections open without having to open as many threads, which would eat up tons of memory (Apaches problem). This allows for high availability. What you have to keep in mind however is that even if you were using a non-blocking file server like Nginx, PHP has many blocking network calls. Since It is running on a single thread, each (for instance) MySQL call would basically halt the server until a response for that MySQL call is returned. Nothing else would get done while this is happening, making your non-blocking server useless. If however you used a non-blocking language like JavaScript (node.js) for your network calls, this would not be an issue. Instead of waiting for a response from MySQL, it would set a handler function to handle the response whenever it becomes available, allowing the server to handle other requests while it is waiting.
For long polling, you would basically send a request, the server would wait 50 seconds before responding. It will respond sooner than 50 seconds if it has anything to report, otherwise it waits. If there is nothing to report after 50 seconds, it sends a response anyways so that the browser does not time out. The response would trigger the browser to send another request, and the process starts over again. This allows for fewer requests and snappier responses, but again, not as good as a socket connection.
I have a website that needs to send notifications to the online clients at real time same as Facebook, after more googling, I found a lot of documentation about push and pull technology. I found from this documentation ways for implementing them using Ajax or Sockets. I need to know what is the best to use in my case and how is it coded using javascript or jquery and php.
I cannot say you what's the best use in your case without knowing your case in detail.
In most cases it is enough to have the clients check with the server every one or two seconds, asking if something new has happened. I prefer this over sockets most of the time because it works on every web server without any configuration changes and in any browser supporting AJAX, even old ones.
If you have few clients (because every client requires an open socket on the server) and you want real realtime, you can use websockets. There are several PHP implementations, for example this one: http://code.google.com/p/phpwebsocket/
If you can ensure that there will be only single browser open per logged in user then you can apply this long polling technique easily.
Policy for Ajax Call:
Do not make request every 2 seconds.
But wait and make request only after 2 seconds of getting response from previous request.
If a request does not respond within 12 seconds then do not wait send a fresh request. This is connection lost case.
Policy for server response:
if there is update response immediately. to check if there is update rely on session ; (better if you could send some hint from client side like latest message received; this second update checking mechanism will eliminate the restriction of single browser open as mentioned above)
otherwise sleep() for 1 second; (do not use infinite loop but use sleep) and then check whether there is update; if update is there respond; if not sleep again for 1 second; repeat this until total 10 seconds has elapsed and then respond back with no update
If you apply this policy (commonly known as long polling), you will find processor usage reduced from 95% to 4% under heavy load case.
Hope this explains. Best of luck.
Just use apply the long-polling technique using jQuery.
Sockets are not yet supported everywhere and also you would need to open a listening socket on the server for this to work.
I've got a small php web app I put together to automate some manual processes that were tedious and time consuming. The app is pretty much a GUI that ssh's out and "installs" software to target machines based off of atomic change #'s from source control (perforce if it matters). The app currently kicks off each installation in a new popup window. So, say I'm installing software to 10 different machines, I get 10 different pop ups. This is getting to be too much. What are my options for kicking these processes off and displaying the results back on one page?
I was thinking I could have one popup that dynamically created divs for every installation I was kicking off, and do an ajax call for each one then display the output for each install in the corresponding div. The only problem is, I don't know how I can kick these processes off in parallel. It'll take way too long if I have to wait for each one to go out, do it's thing, and spit the results back. I'm using jQuery if it helps, but I'm looking mainly for high level architecture ideas atm. Code examples are welcome, but psuedo code is just fine.
I don't know how advanced you are or even if you have root access to your server which would be required, but this is one possible way.. it uses several different technologies, and would probably be suited for a large scale application rather than a small. But I'll advise you on it anyway.
Following technologies/stacks are used (in addition to PHP as you mentioned):
WebSockets (on top of node.js)
JSON-RPC Server (within node.js)
Gearman
What you would do, is from your client (so via JavaScript), when the page loads, a connection is made to node.js via WebSockets ) you can use something like socket.io for this).
Then when you decide that you want to do a task, (which might take a long time...) you send a request to your server, this might be some JSON encoded raw body, or it might just be a simple GET /do/something. What is important is what happens next.
On your server, when the job is received, you kick off a new job to Gearman, by adding a Task to your server. This then processes your task, and it will be a non blocking request, so you can respond immediately back to the client who made the request saying "hey we are processing your job".
Then, your server with all of your Gearman workers, receives the job, and starts processing it. This might take 5 minutes lets say for arguments sake. Once it has finished, the worker then makes a JSON encoded message which it sends to your node.js server which receives it via JSON-RPC.
After it grabs the message, it can then emit the event to any connections which need to know about it via websockets.
I needed something like this for a project once and managed to learn the basics of node.js in a day (having already a strong JS background). The second day I was complete with a full push/pull messaging job notification platform.
First of all, I am completely new on many stuff, so I will welcome any inputs, including suggestions, existing projects, existing models, etc.
My current problems are:
The background service maintains a queue of tasks. The background service is written in C++ or python.
When a client clicks "Create Task" button in browser, the information will be sent to web server and the web server script (written in PHP) will initiate an RPC call to the background service to append the task to the internal queue.
The client browser will initiate an AJAX request to wait for the completion of the task. The AJAX request will hold until the task is completed (or failed) or the client cancels the request.
Thus, I need an low cost way to get the task progress which is run on a background service process.
I can think of two ways:
The background service can inform the server AJAX script about the progress pro-actively. This is low cost but I actually do not know how to do it. Does any RPC framework provides such asynchronous call back? Currently the RPC framework I decided to use is Thrift because of its multi-languages support.
The AJAX script on server side will make an RPC call to get current progress every a few seconds, and sleep in between. Upon completion, the AJAX script will return, otherwise it will just let the client browser wait by not returning. This is actually simpler but I am not sure about its cost. Note that delay isn't an issue to me here because I suppose that the clients are okay to wait for a few more seconds.
Is there any common way/model to deal with this problem?
Thanks for the help.
Depends on how you code it. The common way to do it is to make a javascripted ajax request every 1-3 seconds or so and poll the progress from the server.
This will intermediately close the connection and be more gentle to the server. If you use a persistent connection (WebSockets also fall into this category), you will keep the server busy. Besides, a "sleep" keeps the CPU busy - which is something I would try to avoid if I were you. On the other hand, if you've got the resources for that...
I can only repeat myself: it depends on how you code it and what you expect of it in the end.
If you want the client do some more work and treat the server gentle, choose your 1st option and if you think your server can handle it, choose the 2nd option and go "persistent" and even use WebSockets (which represent persistent connections to your server - remember that they aren't widely supported by web-browsing clients yet either).
Although I think that in the end - the trade-off of a simple progress compared to hogging your server CPU with constant sleeps and some persistent connections on-top of that will make you choose your 1st option: poll the server script for the progress value every x secs from the client side. Btw.: it's what Twitter does and their servers survived until today! ;)
I think, You can use WebSockets for that.
You can use WebSockets.
Establish a WebSockets connection between the client and a web service that has access to the information you need to pass to the client.
With web sockets, you don't need to poll the server asking it for progress, but rather have the server notify the client whenever it's ready.
A backwards compatible implementation would be long polling.
Cheers