This is a re-write of an earlier post that got lost due to data corruption.*
WebSockets were part of the HTML5 draft specifications but have since been moved into their own section. Currently supported by Google Chrome, Apple Safari, and Firefox 4.0 (beta). Support for IE is not forthcoming, which leaves about 70% of the browsers in the dark. WebSockets provide some amazing opportunities for development, especially when working with live / streaming data. What do we do?
Introduce the Flash Socket. Flash Sockets are native socket connections. They have a few limitations (must have flash, flash policy file) but they are well worth it to ensure that the majority of people have access to your application. Currently this is supported in IE 8+, FF 3+, and Chrome, as well as any browser that supports native WebSockets. I’ve also had good success with Safari, but the goal here was IE support, which we now have.
What you will need
Starting from the client side and progressing to the server:
- Node.js (more below)
- web-socket-js (client side Flash Sockets)
- node-websocket-server (Node WebSocket implementation)
- Flash policy file server (I will explain how to make this)
- Something to server the HTML page, as you can’t use a
file:///URI with Flash Sockets.
Expect the configure to go quickly, and the install to take upwards of six to eight minutes. After this you would be able to run
node --version and receive the version string. If not, I refer you to Node’s Google Group for help installing Node. Do not proceed until you have Node installed.
We will be building a very basic application that sends messages spaced one second apart containing the current date to the web page. While the practical applications for this are limited, it is a simple, yet effective, introduction and proof-of-concept. The concept here being that WebSockets are available cross browser and easy to develop.
The client side is particularly easy. There are three files you need to include,
socket.js. Then you need to write a short
script section that will set the swf location.
After that is done we can setup our WebSocket code and handlers.
Define the output function.
And the rest of the HTML page.
Remember that Flash Policy File I mentioned earlier? Yep, have to implement it. Flash attempts to ensure security by checking two places, port 843 and the destination port. It’s always good to run a separate Flash Policy Server because Flash player will by default attempt for three seconds on port 843 before moving on. This will delay your WebSocket by three seconds.
The Flash Policy Server (also node) is pretty basic.
domains is a paired array of domains and ports. The above will allow any connecting domain to connect to any port as a socket. If you desire more security, you can limit to your own domain and a specific port.
The Flash Policy server binds to a low port (843) so you will have run it under
sudo or root.
Ensure that you have a “Flash server listening” log line before continuing. After you have that setup you can work on the actual server side code.
Server side isn’t much more difficult, in fact it could be easier to understand then the client.
Then how we handle WebSocket connections
We are going to add a message listener even though we aren’t using that here.
Setup an interval (1000 msec = 1 second) to send the date.
Closing clears the interval and broadcasts a message saying so.
Finally, listen to port 40132. Port number was pulled out of a hat.
That wraps this up, if anything is confusing drop me a comment and I’ll see what I can do to clear it up.
I have this “live” under joshuakehn.com/socketexample if you want to see it. You can also access this “shell style” with the following handshake:
GET /echo HTTP/1.1 Host: localhost Connection: Upgrade Upgrade: WebSocket
This will be answered with
HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade WebSocket-Origin: undefined WebSocket-Location: ws://joshuakehn.com/echo WebSocket-Protocol: *
And follow with a list of times. Terminal output isn’t pretty, but you get the gist of it.