Websockets are a cool, cutting-edge technology wrapped into HTML5. Basically, you can open a websocket to enable persistent, 2-way communication with a web server. The client (user interface) can spontaneously send messages, and the server can send messages too.
Existing technology (JavaScript) requires everything to be started by the client – the server can’t send anything to the client that the client hasn’t requests. So scripts need to be constantly refreshing and re-requesting data that might not have changed. Websockets work more on a “push” basis and let new data come down the pipe whenever.
Unfortunately, most (all I can find, anyway) websocket implementations require a specific server application to work. People will run Apache on ports 80 and 443 (http and https) and run another system (typically Node.js) on another port (i.e. 8000 or 8080) to handle websocket requests.
This works, obviously, but it’s got some drawbacks.
I have a plugin I want to build that would greatly benefit from using websockets within WordPress. But if a user needs to install a second web server (usually impossible for people with shared hosting), then it won’t work as a plugin.
So, for any of you who have experience, how would you make WordPress compatible with websockets? Would you make WordPress handle the communication itself, or bundle another mini-server script into the plugin? If you’ve done this already, how did you accomplish it without breaking WordPress itself?
Possible resources?
9/21/11 Update
With all the talk of how Apache (the most commonly installed server for running WP on a shared host) can’t really handle websockets natively, I’m wondering about an alternative. Several plugins (JetPack, for example) talk to an external service or API to generate content.
Stats requests content from Automattic. Akismet sends data back and forth from an external server. After the Deadline submits content at publish time. A few SEO tools pass things back-and-forth through external systems.
So as an alternative to housing the websocket code within a WordPress plugin, would it be feasible to host a websocket service in a central location and have a WordPress frontend interact with that instead?
WebSockets use the websockets protocol: WS:/example.com/yourscript.js and open a synchronous connection – meaning the connection is held open and dedicated to the browser.
httpd servers, like apache2 (used by most shared hosting providers) use the http protocol:
http://example.com/yourscript.js
and open an asynchronous connection – meaning that no connection is held open between the server and the browser. (You can prolong open connections, modestly, by setting certain configuration parameters – but generally speaking, it’s asynchronous.)As you can imagine, maintaining open connections between the browser and the server dedicates more server resources to each browser connection, and is therefore more taxing of server resources than dropping connections after each request. Shared hosting providers are understandably disinclined to support WS on shared hosting.
While certain shared hosts may have mod_python installed, thereby allowing your plugin users to run pywebsocket, pywebsocket’s own documentation clearly state that “pywebsocket is intended for testing or experimental purposes.”
So, while one may imagine a plugin bundling python code to create a pywebsocket server, given an apache server that supports it, I don’t believe it would ever be a reasonable to distribute a plugin that did so.
In response to your update, in my opinion and based on the research I have done, that would be the very best option. Even better would be to create the front end plugin and create the external websocket service to talk with the plugins, and charge a fee for it so you can monetize your idea, if you want. You could even provide the source code for the websocket service and create a setting in the plugin to set where (which domain/IP and port) the websocket service is located.
Forget the “classic” apache2 – apache2-mpm-prefork – for this purpose. Maybe apache2-mpm-event could handle this, but it is experimental. Since apache2 is not event-driven, the problem, described by @marfarma does exist. You’ll need an event-driven web server for this kind of serving, for example cherokee or nginx.
nginx can be a real benefit for WordPress (as wordpress.com uses it as their server too), and it can proxy specified requests to a node.js service for example.
Some examples in the topic:
I also made a small tutorial for nginx + php-fpm + wordpress setup.
Another potential solution is to use a third-party web sockets provider, I’ve played around a bit with Pusher (http://pusher.com/) a bit, there’s an API you can tap into that might work well for what you’re trying to do. I’ve been contemplating how I could make use of it in my own WordPress sites.
A possible disadvantage is that other people trying to use your plugin would also have to get a Pusher account to make it work. It’s a lot easier to work with than installing your own Web Sockets server and having to maintain it, that would actually be an advantage actually when it comes to others trying to use your plugin.
Short answer is: yes, it’s do-able. I might look into something a bit more distributed than a single point of failure VPS that you host, though. Maybe look into some load-balanced EC2 systems or somesuch? (I’m assuming you have a revenue stream to provide for such conveniences. grin)