Condor is a minimal library for building scalable TCP servers in Erlang.
-module(ping_server).
-behaviour(condor_listener).
%% condor_listener callbacks
-export([init/1]).
-export([handle_packet/2]).
-export([handle_info/2]).
-export([terminate/2]).
init([]) ->
{ok, undefined}.
handle_packet(<<"stop">>, State) ->
{send_and_stop, <<"ok">>, normal, State};
handle_packet(<<"ping">>, State) ->
{send, <<"pong">>, State}.
handle_info(_Msg, State) ->
{ok, State}.
terminate(_Reason, _State) ->
ok.- Reusable supervised connection acceptors
- Neat packet frames and buffers
condor:start_listener(Name, Opts, Module, InitialState) ->
{ok, Pid} | {error, Reason}
Name = atom()
Opts = #{
ip => inet:ip_address(),
port => inet:port_number(),
max_acceptors => non_neg_integer(),
len => 1 | 2,
timeout => non_neg_integer()
}
Module = atom()
InitialState = any()
Pid = pid()
Reason = any()
Opts:
ip: to what IP Condor should bind.port: on what port Condor should listen.max_acceptors: maximum number of socket acceptors, or in other words, maximum number of concurrent connections.len: length of the indicator of a packet’s size.timeout: the time limit, in milliseconds, for a packet to be buffered.
Default Opts:
#{
ip => {127, 0, 0, 1},
len => 2,
timeout => 10000,
max_acceptors => 100
}
condor:stop_listener(Name) -> ok Name = atom()
Behaviour: condor_listener
init(State) -> Result
handle_packet(Packet, State) -> Result
handle_info(Msg, State) -> Result
terminate(Reason, State) -> ok
Result = {ok, State}
| {send, Packet, State}
| {stop, Reason, State}
| {send_and_stop, Packet, Reason, State}
Packet = binary()
State = any()
Reason = atom()
Events that invoke callbacks:
event callback module ----- --------------- new connection ---> Module:init/1 new packet ---> Module:handle_packet/2 receiving a message ---> Module:handle_info/2 packet timeout ---> Module:handle_info/2 connection termination ---> Module:terminate/2
Condor takes care of framing packets. Each packet frame consists of two
segments: Len | Packet.
Len indicates the length of Packet in big-endian order.
The length of Len is two bytes by default, though it can be modified with
the len option.
Condor also takes care of buffering. So, Module:handle_packet/2 is called
only when an entire packet is received. That is, when Packet is buffered
according to the value of Len. Len will then be stripped off, and only
Packet will be passed to Module:handle_packet/2. However, if Packet is
not received completely in Timeout milliseconds (which would be specified
in Opts), Module:handle_info/2 will be invoked with Msg being
{timeout, Buffer :: binary()}.
A callback’s Result:
{send, Packet, State}sendsPacket(in the frame:Len | Packet).{stop, Reason, State}terminates the connection.{send_and_stop, Packet, Reason, State}sendsPacket(in the frame:Len | Packet), and then terminates the connection.
Apache License, Version 2.0