Dmathieu Simplest TCP Server
Dmathieu Simplest TCP Server
The architecture
If you’re getting started with Erlang, you might still be struggling a bit with workers and
supervisors (they are so awesome though).
In this article, we’re going to setup a supervisor which will listen on the port we need to
accept connections for. We will then setup a number of workers, each of them being able to
accept one single connection.
If you’re used to programming in Ruby, we’re going to rebuild Puma in under 100 lines of
code (yes, this is a huge shortcut).
Each worker will start a new one right before starting to handle it’s request, and kill itself at
the end.
The supervisor
-module(hello_tcp_sup).
-behaviour(supervisor).
-export([start_link/0, start_socket/0]).
-export([init/1]).
start_link() ->
init([]) ->
spawn_link(fun empty_listeners/0),
} }.
start_socket() ->
supervisor:start_child(?MODULE, []).
%% a process would keep the count active at all times to insure nothing
%% bad happens over time when processes get killed too much.
empty_listeners() ->
ok.
This supervisor listens on port 5000, and store the socket that we got in exchange.
It then configures a Simplified one for one worker.
The worker
-module(hello_tcp_server).
-behaviour(gen_server).
-export([start_link/1]).
-record(state, {socket}).
start_link(Socket) ->
init(Socket) ->
gen_server:cast(self(), accept),
{ok, #state{socket=Socket}}.
hello_tcp_sup:start_socket(),
{noreply, State#state{socket=AcceptSocket}};
{noreply, State}.
gen_tcp:close(Socket),
{noreply, State};
{noreply, State}.
ok.
The worker starts a new gen_server inside which is tells the tcp server it is ready to accept a
connection.
From there, the worker will be blocked until it receives that connection.
handle_cast/2 will receive async messages we send to the server. In this example, send
only one, accept, which does the actual accepting of connections.
We don’t do this in init/1, as doing so would block the supervisor.
handle_info/2 will receive every message send by the client and send them back to him.
Unless they send quit, in which case it just closes the connection.