File: README.md

package info (click to toggle)
rabbitmq-server 3.3.5-1.1
  • links: PTS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 12,004 kB
  • sloc: erlang: 78,203; python: 3,187; xml: 2,843; makefile: 903; sh: 831; java: 660; perl: 64; ruby: 63
file content (220 lines) | stat: -rw-r--r-- 7,994 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
SockJS family:

  * [SockJS-client](https://github.com/sockjs/sockjs-client) JavaScript client library
  * [SockJS-node](https://github.com/sockjs/sockjs-node) Node.js server
  * [SockJS-erlang](https://github.com/sockjs/sockjs-erlang) Erlang server


SockJS-erlang server
====================

[SockJS](http://sockjs.org) server written in Erlang. Can run with
[Cowboy](https://github.com/extend/cowboy) http server. SockJS-erlang
is in core web-framework agnostic (up to version
[v0.2.1](https://github.com/sockjs/sockjs-erlang/tree/v0.2.1 ) we also
supported
[Misultin](https://github.com/ostinelli/misultin)). SockJS-erlang is
compatible with
[SockJS client version 0.3](http://sockjs.github.com/sockjs-protocol/sockjs-protocol-0.3.html). See
https://github.com/sockjs/sockjs-client for more information on
SockJS.


Show me the code!
-----------------

A simplistic echo SockJS server using Cowboy may look more or less
like this:

```erlang
main(_) ->
    application:start(sockjs),
    application:start(cowboy),

    SockjsState = sockjs_handler:init_state(
                    <<"/echo">>, fun service_echo/3, state, []),

    Routes = [{'_',  [{[<<"echo">>, '...'],
                       sockjs_cowboy_handler, SockjsState}]}],

    cowboy:start_listener(http, 100,
                          cowboy_tcp_transport, [{port,     8081}],
                          cowboy_http_protocol, [{dispatch, Routes}]),
    receive
        _ -> ok
    end.

service_echo(_Conn, init, state)        -> {ok, state};
service_echo(Conn, {recv, Data}, state) -> Conn:send(Data);
service_echo(_Conn, closed, state)      -> {ok, state}.
```

Dig into the `examples` directory to get working code:

  * https://github.com/sockjs/sockjs-erlang/examples/cowboy_echo.erl


How to run the examples?
------------------------

You may need a recent version of Erlang/OTP, at least R14B is recommended.

To run Cowboy example:

    cd sockjs-erlang
    ./rebar get-deps
    ./rebar compile
    ./examples/cowboy_echo.erl

This will start a simple `/echo` SockJS server on
`http://localhost:8081`.  Open this link in a browser and play
around.


SockJS-erlang API
-----------------

Except for the web framework-specific API's, SockJS-erlang is rather
simple. It has just a couple of methods:

 * **sockjs_handler:init_state(prefix, callback, state, options) -> service()**

    Initializes the state of a SockJS service (ie: a thing you can
    access from the browser, it has an url and a code on the server
    side). `prefix` is a binary that must exacty match the url prefix
    of the service, for example, if service will be listening on
    '/echo', this parameter must be set to `<<"/echo">>`. `callback`
    function will be called when a new SockJS connection is
    established, data received or a connection is closed. The value of
    `state` will be passed to the callback and preserved if returned
    value has changed. Options is a proplist that can contain
    following tuples:

     * `{sockjs_url, string()}` - Transports which don't support
       cross-domain communication natively ('eventsource' to name one)
       use an iframe trick.  A simple page is served from the SockJS
       server (using its foreign domain) and is placed in an invisible
       iframe. Code run from this iframe doesn't need to worry about
       cross-domain issues, as it's being run from domain local to the
       SockJS server. This iframe also does need to load SockJS
       javascript client library, and this option lets you specify its
       url (if you're unsure, point it to <a
       href="http://cdn.sockjs.org/sockjs-0.2.min.js"> the latest
       minified SockJS client release</a>, this is the default).
     * `{websocket, boolean()}` - are native websockets enabled? This
       can be usefull when your loadbalancer doesn't support them.
     * `{cookie_needed, boolean()}` - is your load balancer relying on
       cookies to get sticky sessions working?
     * `{heartbeat_delay, integer()}` - how often to send heartbeat
       packets (in ms).
     * `{disconnect_delay, integer()}` - how long to hold session state
       after the client was last connected (in ms).
     * `{response_limit, integer()}` - the maximum size of a single
       http streaming response (in bytes).
     * `{logger, fun/3}` - a function called on every request, used
       to print request to the logs (or on the screen by default).

    For more explanation, please do take a look at
    [SockJS-node readme](https://github.com/sockjs/sockjs-node/blob/master/README.md).

 * **Connection:send(payload) -> ok**

     Send data over an active SockJS connection. Payload should be of
     iodata() type. Messages sent after connection gets closed will be
     lost.

 * **Connection:close(code, reason) -> ok**

     Close an active SockJS connection with code and reason. If code
     and reason are skipped, the defaults are used.

 * **Connection:info() -> proplist()**

     Sometimes you may want to know more about the underlying
     connection. This method returns a proplist with few attributes
     extracted from the first HTTP/websocket request that was coming
     to this connection. You should see:

       * peername - ip address and port of the remote host
       * sockname - ip address and port of the local endpoint
       * path - the path used by the request that started the connection
       * headers - a set of headers extracted from the request that
         may be handy (don't expect to retrieve Cookie header).


The framework-specific calls are more problematic. Instead of trying
to explain how to use them, please take a look at the examples.

 * **type(req() :: {cowboy, request()})**
 * **sockjs_handler:handle_req(service(), req()) -> req()**
 * **sockjs_handler:handle_ws(service(), req()) -> req()**


Stability
---------

SockJS-erlang is quite new, but should be reasonably stable. Cowboy is passes all the
[SockJS-protocol tests](https://github.com/sockjs/sockjs-protocol).

Deployment and load balancing
-----------------------------

SockJS servers should work well behind many load balancer setups, but
it sometimes requres some additional twaks.  For more details, please
do take a look at the 'Deployment' section in
[SockJS-node readme](https://github.com/sockjs/sockjs-node/blob/master/README.md).


Development and testing
-----------------------

You need [rebar](https://github.com/basho/rebar)
([instructions](https://github.com/basho/rebar/wiki/Building-rebar)).
Due to a bug in rebar config handling you need a reasonably recent
version - newer than late Oct 2011. Alternatively, SockJS-erlang is
bundeled with a recent rebar binary.

SockJS-erlang contains a `test_server`, a simple server used for
testing.

To run Cowboy test_server:

    cd sockjs-erlang
    ./rebar get-deps
    ./rebar compile
    ./examples/cowboy_test_server.erl

That should start test_server on port 8081. Currently, there are two
separate test suits using test_server.

### SockJS-protocol Python tests

Once test_server is listening on `http://localhost:8081` you may test it
using SockJS-protocol:

    cd sockjs-protocol
    make test_deps
    ./venv/bin/python sockjs-protocol-dev.py

For details see
[SockJS-protocol README](https://github.com/sockjs/sockjs-protocol#readme).

### SockJS-client QUnit tests

You need to start a second web server (by default listening on 8080)
that is serving various static html and javascript files:

    cd sockjs-client
    make test

At that point you should have two web servers running: sockjs-erlang on
8081 and sockjs-client on 8080. When you open the browser on
[http://localhost:8080/](http://localhost:8080/) you should be able
run the QUnit tests against your sockjs-node server.

For details see
[SockJS-client README](https://github.com/sockjs/sockjs-client#readme).

Additionally, if you're doing more serious development consider using
`make serve`, which will automatically the server when you modify the
source code.