diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 58 |
1 files changed, 45 insertions, 13 deletions
@@ -94,7 +94,6 @@ Following is an example of a "Hello World!" HTTP handler. ``` erlang -module(my_handler). --behaviour(cowboy_http_handler). -export([init/3, handle/2, terminate/2]). init({tcp, http}, Req, Opts) -> @@ -108,6 +107,46 @@ terminate(Req, State) -> ok. ``` +You can also write handlers that do not reply directly. Instead, such handlers +will wait for an Erlang message from another process and only reply when +receiving such message, or timeout if it didn't arrive in time. + +This is especially useful for long-polling functionality, as Cowboy will handle +process hibernation and timeouts properly, preventing mistakes if you were to +write the code yourself. An handler of that kind can be defined like this: + +``` erlang +-module(my_loop_handler). +-export([init/3, info/3, terminate/2]). + +-define(TIMEOUT, 60000). + +init({tcp, http}, Req, Opts) -> + {loop, Req, undefined_state, ?TIMEOUT, hibernate}. + +info({reply, Body}, Req, State) -> + {ok, Req2} = cowboy_http_req:reply(200, [], Body, Req), + {ok, Req2, State}; +info(Message, Req, State) -> + {loop, Req, State, hibernate}. + +terminate(Req, State) -> + ok. +``` + +It is of course possible to combine both type of handlers together as long as +you return the proper tuple from init/3. + +**Note**: versions prior to `0.4.0` used the +[quoted](https://github.com/klaar/quoted.erl) library instead of the built in +`cowboy_http:urldecode/2` function. If you want to retain this you must add it +as a dependency to your application and add the following cowboy_http_protocol +option: + +``` erlang + {urldecode, {fun quoted:from_url/2, quoted:make([])}} +``` + Continue reading to learn how to dispatch rules and handle requests. Dispatch rules @@ -179,21 +218,13 @@ Websocket would look like this: ``` erlang -module(my_ws_handler). --behaviour(cowboy_http_handler). --behaviour(cowboy_http_websocket_handler). --export([init/3, handle/2, terminate/2]). +-export([init/3]). -export([websocket_init/3, websocket_handle/3, websocket_info/3, websocket_terminate/3]). init({tcp, http}, Req, Opts) -> {upgrade, protocol, cowboy_http_websocket}. -handle(Req, State) -> - error(foo). %% Will never be called. - -terminate(Req, State) -> - error(foo). %% Same for that one. - websocket_init(TransportName, Req, _Opts) -> erlang:start_timer(1000, self(), <<"Hello!">>), {ok, Req, undefined_state}. @@ -236,9 +267,10 @@ is the pid to the listener's gen_server, managing the connections. Socket is of course the client socket; Transport is the module name of the chosen transport handler and Opts is protocol options defined when starting the listener. -After initializing your protocol, it is recommended to wait to receive a message -containing the atom 'shoot', as it will ensure Cowboy has been able to fully -initialize the socket. Anything you do past this point is up to you! +After initializing your protocol, it is recommended to call the +function cowboy:accept_ack/1 with the ListenerPid as argument, +as it will ensure Cowboy has been able to fully initialize the socket. +Anything you do past this point is up to you! If you need to change some socket options, like enabling raw mode for example, you can call the <em>Transport:setopts/2</em> function. It is the protocol's |