I'd like to develop a near real time web based chat system. Any suggestions on how to implement this via jQuery, any gotchas to look out for, and what is this Comet thing I keep reading about?
Ideally, I'd like to support up to about 5,000 concurrent chatters.
Comet, also known as Ajax Push, is often refered as "Reverse AJAX". Instead of pulling the information from the server in regular intervals, the data is pushed from the server to the browser when it is needed. That requires an open connection, for which there are several implementations.
I recommend that you use APE. Here is a demo: http://www.ape-project.org/demos/1/ape-real-time-chat.html
Advantage: It will be very responsive
and real-time.
Disadvantage: You need
to setup the APE server on your
webserver machine.
Comet is a "push" tecnology, created to avoiding the client (javascript code) to continously poll the server. This could cause bandwith problem, because you have to create (maybe) a new TCP connection, then contact the http server, he runs some server-side logic and then sends a response to the client. With comet, if the server decide that you should recive some information (e.g., new chat message) he directly send it to the client.
There are several different implementation, you can have a start here.
the simplest implementation tecnique is the hidden iframe, but I'd raccomend the long polling wich is much more controllable.
One more thing, thake a look at HTML5 websokets, wich could be an interesting solution to your problem (not very compatible with current browser, anyway)
Check out Node.js and nowjs for node.js. Node.js helps you build very efficient servers using server side JavaScript and nowjs is a library that allows you to build real time web apps. There is even a example screen cast that puts together a basic chat application in 12 lines of code.
You could also checkout Socket.io which is another node library thats helps you build real time apps by abstracting away different transport mechanisms and giving you a unified interface to code against (supports WebSockets, Flash Sockets, AJAX long polling, JSONP Polling and Forever IFrames).
I realize you tagged your question PHP but if you are seriously considering writing a scalable system with the least amount of effort (relatively speaking) then learning Node.js is worth your time (and the learning curve is not thats steep since you probably already know JS).
Related
I have a web application driven primarily by javascript/ajax, somewhat similar to how google docs work; all people viewing a page will be seeing the same information in relative real-time. It's not crucial that the information is actually real-time, a second or so is fine.
Currently, the application is ajaxing the server every 5 seconds. I was researching server-sent events and they sound like exactly what I need... but this is my understanding: server-sent events essentially just move the polling to the server. The PHP script doing the server-sent events will check the database for changes every X seconds, and send an update to the application when it finds one.
Checking once per second would probably be adequate, but since I'm on shared hosting I want to avoid any unnecessary load possible. Is there way I can subscribe to updates to the database? Or is there a way I can notify the script from other PHP scripts that make changes to the database?
With PHP, polling the DB is the typical way to do this. You could also use TCP/IP sockets to connect to some kind of application server, that sits in front of your database, and knows about all writers and all consumers. I.e. when a write comes in, it both broadcasts it to all consumers and writes it to the DB. The consumers in that examples are the PHP scripts (one per SSE client).
If you use WebSockets, then you need exactly the same architecture, because PHP is single-threaded: each SSE connection is an independent PHP process.
If you switch to using, say, node.js, then that application server can be built-in. (Again, it would work the same way, whether SSE or WebSockets.)
But, you mention you intend to use shared hosting. SSE (and WebSockets, and comet technologies) hold a socket open, which interferes with the economics of shared hosting. So your sockets are likely to get closed regularly. My advice would be to stick with ajax (and therefore DB) polling every 5 seconds, instead of SSE, until your application is worth enough that the $10-$100/month for a real host is not an issue. Then consider using SSE to optimize the latency.
P.S. The decision between SSE and WebSockets is all about write frequency. My guideline is if your clients write data, on average, once a second or more frequently, web sockets are better, because it is keeping the write channel open. If once every 5+ seconds then web sockets does not bring much, compared to just using an Ajax post each time you have data to write. An SSE back-end is simpler to deal with than a WebSockets back-end. (Writes every 1-5 seconds is the grey area.)
What I would recommend is instead of polling the database for changes, you will know when there is going to be a database change because your application will be making that change. I would use web sockets (https://developer.mozilla.org/en-US/docs/WebSockets) and simply push an update to all active clients when any member makes a change.
Here is the difference between Server Send Events and Web Sockets. (In your case Web Sockets are the way to go)
Websockets and SSE (Server Sent Events) are both capable of pushing data to browsers, however they are not competing technologies.
Websockets connections can both send data to the browser and receive data from the browser. A good example of an application that could use websockets is a chat application.
SSE connections can only push data to the browser. Online stock quotes, or twitters updating timeline or feed are good examples of an application that could benefit from SSE.
In practice since everything that can be done with SSE can also be done with Websockets, Websockets is getting a lot more attention and love, and many more browsers support Websockets than SSE.
However, it can be overkill for some types of application, and the backend could be easier to implement with a protocol such as SSE.
I am writing Web chat where you have several one-on-one conversations with people on the screen at the same time. (Basically, like a personal messenger, without group chats).
My technology options seem to be Long Polling and WebSockets, and I'm trying to choose.
The upside with Long Polling is that's it's very easy to implement, and I can return whatever data i want (a customized JSON-object with the data required to update the page).
What I'm afraid of with WebSockets is that there's no native library for it in PHP, so you have to shop between different 3rd party ones, and the concepts seem more complicated, what with channels and subscriptions and what have you.
Browser compatibility is not an issue for me.
Is the performance of Long Polling much poorer than with Websockets? If no, then my decision is easy!
Is there a really simple Websocket server for PHP? Or is the concept so simple I could write my own? (Mozilla has a really simple tutorial on writing a client, but not on a server).
Assuming that your long-polling scheme involves an endpoint hosted by the same web server as your frontend, this will mean two active connections for every user of the application, so you will basically cut the number of users you can support in half. Your websocket server would run on a different port and can bypass your web server, so the connections are a lot of saved overhead with websockets.
Another place websockets save on overhead is that once your connection is established, there is no need for constant requests and responses. Zombie websocket connections are essentially free in terms of both bandwidth and CPU.
Finally, I would not think that long polling would be simpler to implement. Since websockets are designed to do exactly what you want, I think that leveraging an existing websocket package will actually save you some lines of code. I would look at Ratchet (feature-rich) or phpwebsocket (lite), if you want to use PHP.
Long Polling is definitely way much poorer than Werbsockets.
It is not recommended to use whatever websockets library with PHP, specially for chat applications.
I suggest using Python, Ruby or Node.js instead.
How to implement a real fast web chat with PHP?
Has anybody ever wonder why Facebook chat is just so really really fast? even in IE without WebSocket.
Isn't the only way is to setInterval in JS to check for new messages? But I feel it (Facebook chat box) like having instant reaction.
How to implement such great thing with PHP?
The instantaneous chat you're describing is generally acheived by a something called "Long Polling" or, if we're talking about AJAX, "Comet" (Wikipedia talks about it). Polling tends to strain Apache servers, but there are some specialized servers to deal with it like APE. I'm not sure but I think you can do the same with NodeJS and NGINX handles the stress pretty well.
Here's an article here about how to implement a long polling chat with PHP jQuery and AJAX.
Best of luck, and I hope it helped!
I agree with #joseph-szymborski although it would make sense to start looking at WebSocket solutions which fallback to WebSockets via Flash and/or long-polling.
Here are some relevant SO questions:
How to implement facebook like notification on cakephp? - PHP/jQuery
ajax Push system - PHP/Ajax
Apache with Comet Support - the question itself is very good.
PHP Jquery: chat system, what is the Ideal framework for this? - relevant to your question.
If you want to work with PHP or are on shared hosting then I'd recommend looking at a hosted realtime web solution.
You might want to consider Node.js to serve the clients in 'real time' since Long polling with PHP/AJAX may cause strain on your server.
But the implementation itself is an uphill task. Just saying.
Long polling with PHP/AJAX may cause strain on your server.
My typical theoretical implementation of the same:
Create a Node.js server to query a database.
Send variables and/or session data from php to Node js using cURL.
Parse the url in your Node.js server and use the variables to check
for changes in database.
Emit new data if changes occur and send to client.
We need to create a web-based frontend for displaying some data. The problem is that the data needs to be updated about once a second.
For me as a web-developer the obvious solution is AJAX.
Unfortunately, one of the purposes of this web frontend is to be displayed inside of embedded browser window which is expected to run constantly for months or even years. That's it, months of work with no restart / refresh.
During testing we ran a proof of concept interface (which requested a simple set of data each 1,5s) in Safari for over a month. During this period of time, the memory usage of Safari raised from ~30 MB to over 100MB.
Thus we're afraid of stability of such a solution.
I'm wondering if you could recommend us any other technique for this task, possibly with less overhead (when requesting simple sets of data - as in our case - I'm afraid the HTTP headers are very significant part of data)
I would suggest looking into node.js and the now.js plugging, which allows for realtime updates via websockets. It even has support for older browsers, so if the browser does not support websockets, it will do a fall over to either a comet server implementation, AJAX or an iframe.
It's extremely easy to setup on a linux environment, and there's ample documentation to get you started.
It works with javascript and runs on the Google V8 javascript engine, so if you've ever worked with OOP Javascript, you should be able to pick it up relatively easy.
LINKS:
http://nodejs.org/
http://nowjs.com/
How about Adobe AIR as front-end? You can use Flash/FLEX inside which have decent garbage collectors so long running shoudn't be a problem. AIR also allows to write in XHTML and JavaScript so it could be a good option if you're only familiar with those technologies
PHP is not a good choice for this kind of requests. Comet seems to be a good way to receive data from server. You can use for example excellent Tornado (Python) as backend.
ActionScript allows to use TCP sockets so you can write your own protocol for even better performance and use BOOST Asio (C++) or Netty (Java) as scalable backend
Maybe websocket ? Instead of making an AJAX request each X seconds, the server push new data as they comes.
My personal faverite is php4+, mysql, apache or lightpd webserver.
Tough I also suggest Python.
I specialize in what you are mentioning, with that said, will you be actually looking at the screen? If not you should request the page using an http socket or via a wget cronjob on a linux box.
Yes the http header is very important, if you try to strip them out the webserver will issue a "Server - Bad Request" Error.
Let me know what you decide, I have a lot to share :)
I suspect that the problem is not AJAX per se, but using a browser an sich: I don't think any where made with constant running in mind, and I'm assuming that all (re)loading processes will become some form of extra memory in the end.
I think you would be best off to consume your data trough something simple you design yourself. You can obviously produce it on the same spot (server, requestable via HTTP or whatever you like most), but you do not need a complete webbrowser if your goal is first "a couple of years uptime".
Is there a real solution for COMET AND PHP combination? Basically, I've come to a point that I need to update a user home page periodically whenever there is new data in the database. As far as I understand, I need to open a persistent connection between my server and my clients browsers to update the contents of their home page as soon as new info. available without dedicating a lot of resources but I had no luck finding anything clear about this issue. I read many articles suggests that PHP is not a good language to implement COMET. My web application is completely programmed in PHP and I don't want to learn another language but if I'm forced to, Would you suggest a good language to start with? Do you think that I can program an interface just to handle this issue?
Thanks in advance.
The times I've heard people say that PHP was not well suited for COMET (like you said yourself) was because of the way webservers and PHP work -- mostly, because there is one process per page, which means if you want 200 users connected to your server, you'll need 200 processes (which can quickly become a problem for a couple of hundred more users).
Maybe a solution to that problem would be to use nginx_http_push_module ?
I've not tried it (yet ?), but it might be just what we need...
I was working on a school project and ran into the exact same problem. Because each PHP process has so much memory overhead, it's impossible to support to many connections per box. It was at this point I decided to switch to using BOSH and XMPP. This is a rather new "wave" of technology but there is already quite a few libraries to help you on your way. I would suggest using Strophe and XMPPHP. Then your clients can connect to a BOSH server (I'm using Openfire) and that can scale to thousands of active connections per server.
You don't have to learn a new language to implement such a feature.
For example, you could use Quercus (Java implementation of PHP) and implement a server Comet application using the JVMs memory management model.
There are solutions you need:
almost COMET solution (uses php and one file written with perl):
http://translate.google.com/translate?js=y&prev=_t&hl=ru&ie=UTF-8&layout=1&eotf=1&u=http://dklab.ru/lib/dklab_multiplexor/&sl=ru&tl=en
exact COMET solution in php (this is what you want, I think):
http://translate.google.com/translate?hl=ru&sl=ru&tl=en&u=http://dklab.ru/lib/dklab_realplexor/
You would first need to understand what is a comet application like. The concept involved in building a comet application are explained at wiki at Comet (programming)
What you need to understand is that you can use any programming language to build a comet application as long as it follows the concepts explained at wiki
1.Ajax with long polling
2.Streaming
You can check some sample code at Simple “Long Polling” example code
Now coming to the problems -
1.You use ajax long polling then the browser(ajax request) would keep polling the server for data. This may eat up memory on the server or slow down the browser after some time.
Few Suggestions
JQuery PeriodicalUpdater (AJAX long polling/server polling)
Handling Long Polling
RobertFischer / JQuery-PeriodicalUpdater
What you need to check to implement this -
a) How often do you expect data to be updated on the server.
b) How much time the server side script would run to check, fetch and process data before sending it to the client side.
2.You can implement streaming by using the following -
How to implement COMET with PHP
Lightstreamer Dojo
Dojo Charting + Lightstreamer Comet Demo
Demo
Ajax Push Engine or The APE Project
What you need to check for this -
a) Will your hosting provider allow you to install these on hosting servers
b) Your RAM and Bandwidth utilization (You will need a dedicated server with package that gives you lots of RAM and Bandwidth)
It depends on what and how your requirements are. You will have to analyze and approach.
If what you are implementing is a small application you can go for Ajax Long polling given the fact that you analyzed and handled the negatives of this approach.
If you have a large application you can go for steaming.
Ajax with long polling is a easy solution, there are plugins in jquery and any other major js framework to help you do this.
Node.js seems like a pretty sweet solution for stuff like this. (Still a little gamey for production but cool all the same). PHP is a horrible environment for stuff like this, you have to change the way the server interacts with requests because you are no longer immediately responding. Python has a handful of servers like Twisted that are great for this because they let you be the server. No matter what language you write it in you've got to alter the typical request/response model. (Glassfish's Grizzly Comet server does this for Java as an example)
You should try Dmitry Koterov's Realplexor, which is a comet server, that provides Javascript and PHP APIs.
Readme.txt in english is provided in the package.