wsock
wsock copied to clipboard
Erlang library to build WebSocket clients and servers
#WSOCK
- About
- Examples
- Writing clients
- Upgrading the connection
- Sending data
- Receiving data
- Control messages
- Writing servers
- Upgrading the connection
- Sending data
- Receiving data
- Control messages
- Documentation
- Tests
- Contributing
- Author
- License
About
Wsock are a set of modules that can be used to build Websockets (RFC 6455 compliant) clients an servers.
Examples
wsserver (a WebSockets server) and wsecli (a WebSockets client) are projects which use wsock.
Writing clients
Don't forguet to include the wsock headers file:
-include_lib("wsock/include/wsock.hrl").
Upgrading the connection
Create and send an upgrade request to the server.
-
Build a handshake request:
HandshakeRequest = wsock_handshake:open(Resource, Host, Port) -
Encode the handshake to send it to the server:
BinaryData = wsock_http:encode(HandshakeRequest#handshake.message) -
Receive and validate the handshake response:
{ok, HandshakeResponse} = wsock_http:decode(Data, response) wsock_handshake:handle_response(HandshakeResponse, HandshakeRequest)If the received HTTP message is fragmented
wsock_http:decodewill return the atomfragmented_http_message. Check the section upgrading the connection when writing servers for more info.
Sending data
Once the connection has been stablished you can send data through it:
Message = wsock_message:encode(Data, [mask, text]) %text data
Message = wsock_message:encode(Data, [mask, binary]) %binary data
Receiving data
-
If there is no previous fragmented message:
ListOfMessages = wsock_message:decode(Data, []) -
If the previously received message was fragmented pass it as a parameter:
ListOfMessages = wsock_message:decode(Data, FragmentedMessage, [])
Check wsock.hrl for a description of the message record.
Control messages
-
Ping/pong messages:
ListOfMessages = wsock_message:encode(Data, [mask, ping]) ListOfMessages = wsock_message:encode(Data, [mask, pong]) -
Close messages (with or without reason):
ListOfMessages = wsock_message:encode({StatusCode, Payload}, [mask, close]) ListOfMessages = wsock_message:encode([]], [close]) % If no payload
Writing servers
Don't forget to include the wsock headers file:
-include_lib("wsock/include/wsock.hrl").
Upgrading the connection
Accept upgrade requests from your clients.
-
Decode the http-handshake request:
{ok, OpenHttpMessage} = wsock_http:decode(Data, request), {ok, OpenHandshake} = wsock_handshake:handle_open(OpenHttpMessage)If the received HTTP message is fragmented
wsock_http:decodewill return the atomfragmented_http_message. In this case, buffer the partial HTTP message until more data is received and try again.fragmented_http_message = wsock_http:decode(Data, request), %% Buffer Data %% … some time passes and then more data is received %% Concat the new data to the buffered one and pass it to wsock_http:decode {ok, OpenHttpMessage} = wsock_http:decode(<<Buffered/binary, NewData/binary>>, request), … -
Get handshake key to generate a handshake response:
ClientWSKey = wsock_http:get_header_value("sec-websocket-key", OpenHandshake#handshake.message), {ok, HandshakeResponse} = wsock_handshake:response(ClientWSKey) -
Encode the http-handshake response:
ResponseHttpMessage = wsock_http:encode(HandshakeResponse#handshake.message)
Now all you have to do is send the handshake response over the wire to upgrade the HTTP connection to a WebSockets one.
Receiving data
-
If there is no previous fragmented message:
ListOfMessages = wsock_message:decode(Data, [masked]) -
If the previously received message was fragmented pass it as a parameter:
ListOfMessages = wsock_message:decode(Data, FragmentedMessage, [masked])Check wsock.hrl for a description of the message record.
Sending data
Once the connection has been stablished you can send data through it:
ListOfMessages = wsock_message:encode(Data, [text]) % text data, servers don't mask data
ListOfMessages = wsock_message:encode(Data, [binary]) % binary data
Control messages
-
Ping/pong messages:
ListOfMessages = wsock_message:encode(Data, [ping]) ListOfMessages = wsock_message:encode(Data, [pong]) -
Close messages (with or without reason):
ListOfMessages = wsock_message:encode({StatusCode, Payload}, [close]) ListOfMessages = wsock_message:encode([]], [close]) % If no payload
Documentation
Documentation for the modules can be generated. Run:
rake doc
or, in case you don't have rake installed:
rebar doc
Tests
Unit test where done with the library espec by lucaspiller. To run them:
rake spec
or, in case you don't have rake installed:
rebar compile && ERL_LIBS='deps/' ./espec test/spec/
Contribute
If you find or think that something isn't working properly, just open an issue.
Pull requests and patches (with tests) are welcome.
Author
This stuff has been writen by Farruco sanjurjo
- @madtrick at twitter
- Email at [email protected]
License
Copyright [2012] [Farruco Sanjurjo Arcay]
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.