diff options
author | Loïc Hoguin <[email protected]> | 2015-08-22 13:15:08 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2015-08-22 13:15:08 +0200 |
commit | f4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42 (patch) | |
tree | 5f73255bbd51d46fccf371ff7cdd67c6bea8e7b7 /guide/protocols.md | |
parent | d30408b2e8c14c0e56ce997f5aff0010c03cef0b (diff) | |
download | ranch-f4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42.tar.gz ranch-f4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42.tar.bz2 ranch-f4c6da56d4fe9494f4fe23c48b8d7c3c1e9e6b42.zip |
Convert the documentation to Asciidoc
Diffstat (limited to 'guide/protocols.md')
-rw-r--r-- | guide/protocols.md | 121 |
1 files changed, 0 insertions, 121 deletions
diff --git a/guide/protocols.md b/guide/protocols.md deleted file mode 100644 index 0cf0dc1..0000000 --- a/guide/protocols.md +++ /dev/null @@ -1,121 +0,0 @@ -Protocols -========= - -Purpose -------- - -A protocol handler starts a connection process and defines the -protocol logic executed in this process. - -Writing a protocol handler --------------------------- - -All protocol handlers must implement the `ranch_protocol` behavior -which defines a single callback, `start_link/4`. This callback is -responsible for spawning a new process for handling the connection. -It receives four arguments: the name of the listener, the socket, the -transport handler being used and the protocol options defined in -the call to `ranch:start_listener/6`. This callback must -return `{ok, Pid}`, with `Pid` the pid of the new process. - -The newly started process can then freely initialize itself. However, -it must call `ranch:accept_ack/1` before doing any socket operation. -This will ensure the connection process is the owner of the socket. -It expects the listener's name as argument. - -``` erlang -ok = ranch:accept_ack(Ref). -``` - -If your protocol code requires specific socket options, you should -set them while initializing your connection process, after -calling `ranch:accept_ack/1`. You can use `Transport:setopts/2` -for that purpose. - -Following is the complete protocol code for the example found -in `examples/tcp_echo/`. - -``` erlang --module(echo_protocol). --behaviour(ranch_protocol). - --export([start_link/4]). --export([init/4]). - -start_link(Ref, Socket, Transport, Opts) -> - Pid = spawn_link(?MODULE, init, [Ref, Socket, Transport, Opts]), - {ok, Pid}. - -init(Ref, Socket, Transport, _Opts = []) -> - ok = ranch:accept_ack(Ref), - loop(Socket, Transport). - -loop(Socket, Transport) -> - case Transport:recv(Socket, 0, 5000) of - {ok, Data} -> - Transport:send(Socket, Data), - loop(Socket, Transport); - _ -> - ok = Transport:close(Socket) - end. -``` - -Using gen_server ----------------- - -Special processes like the ones that use the `gen_server` or `gen_fsm` -behaviours have the particularity of having their `start_link` call not -return until the `init` function returns. This is problematic, because -you won't be able to call `ranch:accept_ack/1` from the `init` callback -as this would cause a deadlock to happen. - -There are two ways of solving this problem. - -The first, and probably the most elegant one, is to make use of the -`gen_server:enter_loop/3` function. It allows you to start your process -normally (although it must be started with `proc_lib` like all special -processes), then perform any needed operations before falling back into -the normal `gen_server` execution loop. - -``` erlang --module(my_protocol). --behaviour(gen_server). --behaviour(ranch_protocol). - --export([start_link/4]). --export([init/4]). -%% Exports of other gen_server callbacks here. - -start_link(Ref, Socket, Transport, Opts) -> - proc_lib:start_link(?MODULE, init, [Ref, Socket, Transport, Opts]). - -init(Ref, Socket, Transport, _Opts = []) -> - ok = proc_lib:init_ack({ok, self()}), - %% Perform any required state initialization here. - ok = ranch:accept_ack(Ref), - ok = Transport:setopts(Socket, [{active, once}]), - gen_server:enter_loop(?MODULE, [], {state, Socket, Transport}). - -%% Other gen_server callbacks here. -``` - -The second method involves triggering a timeout just after `gen_server:init` -ends. If you return a timeout value of `0` then the `gen_server` will call -`handle_info(timeout, _, _)` right away. - -``` erlang --module(my_protocol). --behaviour(gen_server). --behaviour(ranch_protocol). - -%% Exports go here. - -init([Ref, Socket, Transport]) -> - {ok, {state, Ref, Socket, Transport}, 0}. - -handle_info(timeout, State={state, Ref, Socket, Transport}) -> - ok = ranch:accept_ack(Ref), - ok = Transport:setopts(Socket, [{active, once}]), - {noreply, State}; -%% ... -``` |