This repository has been archived by the owner on Oct 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Stand alone Client connection example
Pouriya Jahanbakhsh edited this page Jul 9, 2017
·
1 revision
check_echo_server.erl
-module(check_echo_server).
-behaviour(sockerl).
-export([start_link/2
,connector_init/2
,handle_packet/3
,timeout/2
,handle_disconnect/2
,terminate/3
,code_change/3]).
start_link(Port, Sec) ->
Host = "127.0.0.1",
sockerl:start_link_connector(?MODULE
,Sec % Init argument
,Host
,Port
,[{connector_debug, [trace]}]).
connector_init(Sec, _Sock) ->
%% I want to send packet after spending Sec
%% I will do this in timeout/2
%% I don't specify {state, _}, my state will be atom 'undefined'
{ok, [{timeout, Sec * 1000}]}.
handle_packet(_Packet, undefined=_State, SMD) -> % SMD: Sockerl MetaData
%% Echo server replies my packet
%% I want to send next packet after spending previous timeout+1
%% I will do this in timeout/2 too
{ok, [{timeout, sockerl_metadata:get_timeout(SMD) + 1000}]}.
handle_disconnect(undefined = _State, _SMD) ->
%% Will exit with reason 'closed_by_remote' if server closes connection
{stop, closed_by_remote}.
timeout(undefined = _State, _SMD) ->
%% I will send timestamp (in seconds) to server
{Me, S, _Mi} = os:timestamp(),
TSBin = erlang:integer_to_binary((Me * 1000000) + S),
%% I don't change 'timeout' value, process keeps its last value and
%% after sending packet if server replies, i will change it (add 1
%% second to it) and if server doesn't reply, after that timeout
%% This function will called again.
{ok, [{packet, TSBin}]}.
terminate(_Reason, undefined = _State, _SMD) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
I implemented server in here.
Before starting server, try connecting to it and see the clean error information:
Erlang/OTP 19 [erts-8.3] [source-d5c06c6] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V8.3 (abort with ^G)
1> check_echo_server:start_link(8080, 1).
** exception exit: {socket_connect,[{reason,econnrefused},
{info,"connection refused"},
{transporter,sockerl_tcp_transporter},
{host,"127.0.0.1"},
{port,8080},
{options,[{connector_debug,[trace]}]}]}
Start echo_server
in other terminal:
Erlang/OTP 19 [erts-8.3] [source-d5c06c6] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V8.3 (abort with ^G)
1> echo_server:start(8080).
{ok,<0.178.0>}
Reconnect the client:
2> check_echo_server:start_link(8080, 1).
{ok,<0.278.0>}
*DBG* Sockerl connector "<0.278.0>" sent packet <<"1499083529">>
*DBG* Sockerl connector "<0.278.0>" got packet "1499083529"
*DBG* Sockerl connector "<0.278.0>" sent packet <<"1499083531">>
*DBG* Sockerl connector "<0.278.0>" got packet "1499083531"
*DBG* Sockerl connector "<0.278.0>" sent packet <<"1499083534">>
*DBG* Sockerl connector "<0.278.0>" got packet "1499083534"
*DBG* Sockerl connector "<0.278.0>" sent packet <<"1499083538">>
*DBG* Sockerl connector "<0.278.0>" got packet "1499083538"
*DBG* Sockerl connector "<0.278.0>" sent packet <<"1499083543">>
*DBG* Sockerl connector "<0.278.0>" got packet "1499083543"
*DBG* Sockerl connector "<0.278.0>" sent packet <<"1499083549">>
*DBG* Sockerl connector "<0.278.0>" got packet "1499083549"
...
Close connection in server:
2> [{_,Con}] = sockerl:get_server_connections(echo_server).
[{#Port<0.40773>,<0.185.0>}]
3> sockerl:stop_connector(Con).
ok
=ERROR REPORT==== 3-Jul-2017::16:37:39 ===
** Sockerl connector "<0.185.0>" terminating
** Reason for termination == "normal"
** State == "15"
Client process should exit with reason 'closed_by_remote':
...
*DBG* Sockerl connector "<0.278.0>" sent packet <<"1499083648">>
*DBG* Sockerl connector "<0.278.0>" got packet "1499083648"
** exception error: closed_by_remote
=ERROR REPORT==== 3-Jul-2017::16:37:39 ===
** Sockerl connector "<0.278.0>" terminating
** Reason for termination == "closed_by_remote"
** State == "undefined"