diff --git a/README.rdoc b/README.rdoc
index ef9ed88..dd37f04 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -1,5 +1,128 @@
= faye-websocket-parser {
}[http://travis-ci.org/faye/faye-websocket-ruby]
+This library is a set of WebSocket parsers extracted from the
+{Faye}[http://faye.jcoglan.com] project. It provides parsing and serialization
+functionality for the {draft-75}[http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75],
+{draft-76}[http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76],
+and {hybi-07}[http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07]
+and later versions of the protocol, and can select the right parser to use
+based on the client handshake. It can be used with any Ruby TCP library to
+create both servers and clients.
+
+
+== Usage
+
+For building server-side sockets, you need to provide a Rack-style +env+ hash
+representing the client handshake for Faye to select the right parser for you.
+For client-side sockets, only the Faye::WebSocket::HybiParser may be
+used.
+
+
+=== Server-side
+
+To process the server side of a WebSocket connection, you need to build a Rack
++env+ hash. This hash will contain a subset of following keys as strings, which
+map to string header values unless states otherwise. The set of keys present
+will depend on which version of the protocol the client is using.
+
+* +HTTP_CONNECTION+
+* +HTTP_HOST+
+* +HTTP_ORIGIN+
+* +HTTP_UPGRADE+
+* +HTTP_SEC_WEBSOCKET_KEY+
+* +HTTP_SEC_WEBSOCKET_KEY1+
+* +HTTP_SEC_WEBSOCKET_KEY2+
+* +HTTP_SEC_WEBSOCKET_PROTOCOL+
+* +HTTP_SEC_WEBSOCKET_VERSION+
+* +HTTP_X_FORWARDED_PROTO+, should have the value 'https' if the
+ socket is using an encrypted connection
+* rack.input, an +IO+ object representing the request body
+* +REQUEST_METHOD+, the request's HTTP verb
+* +REQUEST_URI+, the request's path and query string
+
+Given an +env+ hash, the first thing to do is check whether it represents a
+valid WebSocket request.
+
+ is_websocket = Faye::WebSocket.websocket?(env)
+
+If it is a valid WebSocket, you can get a parser for it like so:
+
+ parser = Faye::WebSocket.parser(env).new(handler, options)
+
+See 'Parser API' below for the +parser+ interface and the API expected on the
++handler+ object. +options+ is an optional hash containing:
+
+* :masking - optional, boolean flag saying whether to mask outgoing
+ message frames. This is not required for server-side handlers.
+* :protocols - optional, an array of strings that will be used to set
+ the Sec-WebSocket-Protocol header for subprotocol negotiation.
+
+To complete the connection, you need to send a response to the client's
+handshake, which you do by writing parser.handshake_response to the
+TCP socket:
+
+ socket.write(parser.handshake_response)
+
+At this point the handshake might still not be complete. In some situations
+part of the client's handshake is deferred until the server has sent this
+response, and the server should not begin sending message frames until the
+handshake is done. You should check the connection is ready to exchange
+messages using:
+
+ can_send_messages = parser.open?
+
+After this setup is done, use the parser API detailed below to process data.
+
+
+=== Client-side
+
+If you're building a client, construct a parser like this:
+
+ parser = Faye::WebSocket:HybiParser.new(handler, options)
+
+The +parser+ interface and the required +handler+ API is documented below under
+'Parser API'. +options+ is a hash containing the following keys:
+
+* :masking - must have the value +true+.
+* :protocols - optional, an array of strings that will be used to set
+ the Sec-WebSocket-Protocol header for subprotocol negotiation.
+
+To make a connection, you must send a WebSocket handshake request over TCP to
+the target server.
+
+ handshake = parser.create_handshake
+ socket.write(handshake.request_data)
+
+handshake.request_data is a string containing the handshake format.
+Send this over an open TCP socket, then parse any data you receive over the
+socket. Here, +chunk+ is a string representing a chunk of input read from the
+socket.
+
+ overflow_bytes = handshake.parse(chunk)
+
+If the handshake is complete, any bytes received after the end of the handshake
+are returned as an array of ints. After parsing each chunk of input, use the
+following to check for handshake completion:
+
+* handshake.complete? returns +true+ if a whole handshake response has
+ been received from the server
+* handshake.valid? returns +true+ if the server's response is valid
+ and allows the client to connect
+* handshake.protocol is either +nil+ or a string containing the first
+ selected subprotocol that matches both our :protocols setting and
+ the server's Sec-WebSocket-Protocol response
+
+Once you know you have a valid connection, you should have the parser process
+the overflow bytes from the handshake parser:
+
+ parser.parse(overflow_bytes)
+
+After this, use the parser API detailed below to handle data tranfer on the
+connection.
+
+
+=== Parser API
+
== License