Permalink
Browse files

Updated readme

  • Loading branch information...
1 parent 74400be commit f00f7c8b68025de6d7476001f20a641021ce0ac8 @majek majek committed Feb 9, 2012
Showing with 100 additions and 93 deletions.
  1. +100 −93 README.md
View
193 README.md
@@ -4,126 +4,133 @@ SockJS family:
* [SockJS-node](https://github.com/sockjs/sockjs-node) Node.js server
* [SockJS-erlang](https://github.com/sockjs/sockjs-erlang) Erlang server
-SockJS-erlang
-=============
-Erlang-based server side component for
-[SockJS](http://sockjs.org). Can run with Cowboy or Misultin.
+SockJS-erlang server
+====================
-See https://github.com/sockjs/sockjs-client for more information on SockJS.
+[SockJS](http://sockjs.org) server written in Erlang. Can run with
+[Cowboy](https://github.com/extend/cowboy) or
+[Misultin](https://github.com/ostinelli/misultin).
-Status
-------
-
-Currently this lags the Node.JS implementation slightly:
-
-* A couple of header-based things haven't been ported from the node server
-* Hasn't been tested much
-* Hasn't been performance-tested at all
+See https://github.com/sockjs/sockjs-client for more information on
+SockJS.
-Some useful application configuration parameters:
+A simplistic echo SockJS server using Cowboy may look more or less
+like this:
-* **sockjs_url** - path to the sockjs library as seen by the client
- (default: "/lib/sockjs.js")
-* **heartbeat_ms** - milliseconds between heartbeat frames
- (default: 25000)
-* **session_close_ms** - milliseconds to keep a session alive after a client connection goes away
- (default: 5000)
-* **json_impl** - JSON library to use, either jiffy, mochijson2 or eep0018
- (default: jiffy (NIF-based))
+```erlang
+main(_) ->
+ application:start(sockjs),
+ application:start(cowboy),
-[Note that the tests test that you can send unicode strings containing \0.
-When using eep0018 you can't; it strips them out. So a few tests will fail.]
+ SockjsState = sockjs_handler:init_state(
+ <<"/echo">>, fun service_echo/2, []),
-Using SockJS-erlang
--------------------
+ Routes = [{'_', [{[<<"echo">>, '...'],
+ sockjs_cowboy_handler, SockjsState}]}],
-You will need either [cowboy](https://github.com/extend/cowboy) or
-[misultin](https://github.com/ostinelli/misultin) installed.
+ cowboy:start_listener(http, 100,
+ cowboy_tcp_transport, [{port, 8081}],
+ cowboy_http_protocol, [{dispatch, Routes}]),
+ receive
+ _ -> ok
+ end.
-### Using cowboy
+service_echo(Conn, {recv, Data}) -> sockjs:send(Data, Conn);
+service_echo(_Conn, _) -> ok.
+```
-The module `sockjs_cowboy` implements both the cowboy_http_handler and
-cowboy_http_websocket_handler behaviours. The procedure
-`sockjs_cowboy:init_state/2` gives you a initial state for the
-handler, given a fallback handler and a dispatch table (both explained
-in a minute, after we visit misultin too).
+And a simplistic echo SockJS server using Misultin may look more or
+less like this:
+```erlang
+main(_) ->
application:start(sockjs),
- application:start(cowboy),
- Routes = [{'_', [{'_', sockjs_cowboy,
- sockjs_cowboy:init_state(Fallback, Dispatch)}]}],
- cowboy:start_listener(http, 100,
- cowboy_tcp_transport, [{port, Port}],
- cowboy_http_protocol, [{dispatch, Routes}])
-### Using misultin
+ SockjsState = sockjs_handler:init_state(
+ <<"/echo">>, fun service_echo/2, []),
-The procedure `sockjs_misultin:init_state/2` produces a request loop
-and a websocket accept loop suitable for use with misultin, given a
-fallback handler and a dispatch table.
+ misultin:start_link(
+ [{port, 8081}, {autoexit, false}, {ws_autoexit, false},
+ {loop, fun (Req) -> handle_http(Req, SockjsState) end},
+ {ws_loop, fun (Req) -> handle_ws(Req, SockjsState) end}]),
+ receive
+ _ -> ok
+ end.
- application:start(sockjs),
- {Loop, WsLoop} = sockjs_misultin:init_state(Fallback, Dispatch),
- {ok, _} = misultin:start_link([{loop, Loop},
- {ws_loop, WsLoop},
- {ws_autoexit, false},
- {port, Port}]);
-
-### Fallback handler and dispatch table
-
-The arguments to `sockjs_cowboy:init_state` and
-sockjs_misultin:init_state` are a procedure for handling requests that
-are not handled by SockJS, and a table of SockJS endpoints.
-
-The fallback is supplied a wrapped request; the procedures in
-`sockjs` may be used to retrieve information in a webserver-neutral
-way, or the request unwrapped with `sockjs:req/1`.
-
- fallback(Request) ->
- "/" ++ Path = sockjs:path(Request),
- case Path of
- "index.html" ->
- sockjs:respond(200, [{"Content-Type", "text/html"}],
- "<html> ... </html>", Request)
- _ ->
- sockjs:respond(404, [], "Not found")
- end
+handle_http(Req, SockjsState) ->
+ case Req:resource([]) of
+ ["echo" | _T] ->
+ sockjs_handler:handle_req(SockjsState, {misultin, Req});
+ _Any ->
+ Req:respond(404,
+ <<"404 - Nothing here (via sockjs-erlang fallback)\n">>)
end.
-The dispatch table gives a map of URL prefixes to SockJS handlers:
+handle_ws(Req, SockjsState) ->
+ case string:tokens(Req:get(path), "/") of
+ ["echo" | _T] ->
+ sockjs_misultin_handler:handle_ws(SockjsState, {misultin, Req});
+ false ->
+ closed
+ end.
- [{echo, fun echo/2},
- {broadcast, fun broadcast/2}]
+service_echo(Conn, {recv, Data}) -> sockjs:send(Data, Conn);
+service_echo(_Conn, _) -> ok.
+```
-This table says that SockJS connections to `/echo` shall be handled by
-`echo/2` and connections to `/broadcast` shall be handled by
-`broadcast/2`. Those two procedures are supplied the connection, and a
-term representing the connection event (initiation, message received,
-etc.).
+Dig into the `examples` directory for more details:
-Development
------------
+ * https://github.com/sockjs/sockjs-erlang/examples/simple_cowboy.erl
+ * https://github.com/sockjs/sockjs-erlang/examples/simple_misultin.erl
-SockJS has a rebar config and may be included as a dependency of rebar
-projects. SockJS does not itself depend on a web server.
+SockJS-erlang API
+-----------------
-To compile from the source repo:
+Except for the web framework-specific API's, SockJS-erlang is rather
+simple. It has just a couple of methods:
- $ make
+ * **sockjs_handler:init_state(prefix, callback, options) -> service()**
+ * **sockjs:send(payload) -> ok**
+ * **sockjs:close(code, reason) -> ok**
-To run tests you need to have `node` and `coffee-script` installed
+The framework-specific calls are more problematic. Instead of trying
+to explain how to use them, please take a look at the examples.
+
+ ** req() :: {cowboy|misultin, request} **
+
+ * **sockjs_handler:handle_req(service(), req()) -> req()**
+ * **sockjs_handler:handle_ws(service(), req()) -> req()**
+
+Status
+------
+
+SockJS-erlang is quite new, but should be reasonably stable.
+
+Cowboy is passing all the tests.
+
+Misulting is behaving well most of the time, with the exception of a
+few websockets issues:
+
+ * https://github.com/ostinelli/misultin/issues/98
+ * https://github.com/ostinelli/misultin/issues/99
+
+Development
+-----------
- $ npm install coffee-script
+To run Cowboy examples:
-Now you're ready to run test server. If you want to use `cowboy`:
+ cd sockjs-erlang
+ rebar -C rebar-cowboy.config get-deps
+ rebar -C rebar-cowboy.config compile
+ ./examples/simple_cowboy.erl
- $ make test
-Or `misultin`:
+To run Misultin examples:
- $ make test HTTP=misultin
+ cd sockjs-erlang
+ rebar -C rebar-misultin.config get-deps
+ rebar -C rebar-misultin.config compile
+ ./examples/simple_misultin.erl
-Both of these will clone the appropriate web server source from github
-and build it. Run the tests or see a demo by visiting
-`http://localhost:8080`.
+This should start a simple `/echo` server on `http://localhost:8081`.

0 comments on commit f00f7c8

Please sign in to comment.