Try Out Low-Latency Connections with WebSockets

I am very excited for the opportunity to write this blog post. OpenShift users asked and we’ve listened! WebSockets support is now live on OpenShift.

What are WebSockets?

WebSockets are a big part of the upcoming HTML5 standard. WebSockets are designed to bring HTTP (and the web world generally) and TCP closer. WebSockets are TCP protocol that uses HTTP as a initiation handshake and then upgrades to the WebSockets protocol. Let’s see how it works (examples are taken from Wikipedia page).

At first the client sends a request to server as simple HTTP request with one small, but important, change. The request contains the Upgrade: websocket header and that means that when the handshake is finished successfully, neither the server nor client is supposed to close the connection, but to start to treat the connection as WebSocket connection and switch to the protocol.

Notice that the Connection: Upgrade header notifies the client that the request to upgrade to WebSockets was well understood.

The important thing about the HTTP based handshake is that when the server does not understand the request, it automatically falls back to standard HTTP and there is no need for separate layers. Yes, you are right, WebSockets do not need any special ports, they just run over existing HTTP layers.

Simple isn’t it? Well, from the perspective of the client YES!, however from the perspective of the server not so much.

The implementation challenge

For OpenShift as a PaaS provider, WebSockets were a big challenge. The routing layer that sits between the user’s browser and your application must be able to route and handle WebSockets. OpenShift uses Apache as a reverse proxy server and a main component to route requests throughout the platform. However, Apache’s mod_proxy has been problematic with WebSockets, so OpenShift implemented a new Node.js based routing layer that provides scalability and the possibility to expand features provided to our users.

The second thing that is problematic is the backend. WebSockets by default will work fine only with Node.js and DIY cartridges. Yeah, I know, it’s pain … but bear with me and let me explain a bit why this problem occurs.

In the cartridges for specific languages we provide preconfigured environments to give our users the best experience possible. As an example, with Ruby we spin up Apache + Passenger to start and maintain your application. You may already see the problem. There is a layer between your application and the routing system (Apache+Passenger) and it needs to be able to handle Websockets, but it does not. Actually all the Apache based deployments are crippled by this problem (Apache+mod_wsgi for Python, Apache+mod_perl for Perl, Apache+mod_php for PHP and Apache+Passenger for Ruby). For running Java applications we use Tomcat6 and JBoss, unfortunately, these are not WebSockets enabled either.

In case of Node.js there is no intermediate layer, and the routing system talks directly to your Node.js application, and because of that, there is no problem to use WebSockets. For now, Node.js applications provide most streamline WebSockets support on OpenShift.

However, with DIY you can run whatever you want. Yes, it’s a bit more painful, but allows you to run some custom server that is WebSockets enabled. I.e. you can use WebSockets with other languages, too, but you need to run those using DIY.

Update: There is one more known complication. When using our preview-deployment of WebSockets with HTTPS and WSS protocols, you will face self-signed certificate. That is because this environment is only temporary to give you insight into upcoming features. Once we move the new routing layer to standard ports 80 and 443, i.e. we move WebSockets support into production, the certificates used will be signed and valid as they are with current deployment.

Current state

We are releasing a preview version of WebSockets support. This means our new routing layer will be available on specific ports for users that want to test and provide feedback on the functionality. Interested? Try it and let us know what was your experience!

How to access Preview WebSockets Support?

You will need to connect to specific ports, as the main routing layer is still Apache based and does not support WebSockets.

So, for plain WebSockets ws:// you will use port 8000 and for secured connections wss:// port 8443. Here’s an example:

WebSockets in HTML

Using WebSockets in your HTML code is very simple. The biggest challenge is making sure users have WebSocket enabled browsers which isn’t that big of a challenge since most modern browser support WebSockets according to Wikipedia.

All the latest browsers except Android browser support the latest specification (RFC 6455) of the WebSocket protocol.

So, how do you use it? Check this JavaScript snippet, which pictures the DOM API to use while implementing WebSockets enabled application.