add tcp channel

This commit is contained in:
anlicheng 2025-04-19 14:26:43 +08:00
parent aa78ccee0a
commit 4bd1f26a35
2 changed files with 117 additions and 1 deletions

View File

@ -41,6 +41,6 @@ start_tcp_server() ->
{acceptors, 10},
{max_connections, 1024}
],
{ok, _} = esockd:open('efka/tcp_server', Port, TransOpts, {sdlan_channel, start_link, []}),
{ok, _} = esockd:open('efka/tcp_server', Port, TransOpts, {tcp_channel, start_link, []}),
lager:debug("[efka_app] the tcp server start at: ~p", [Port]).

View File

@ -0,0 +1,116 @@
%%%-------------------------------------------------------------------
%%% @author licheng5
%%% @copyright (C) 2020, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 10. 12 2020 11:17
%%%-------------------------------------------------------------------
-module(tcp_channel).
-author("licheng5").
-behaviour(gen_server).
%%
-define(PING_TICKER, 15000).
%% API
-export([start_link/2]).
-export([publish_command/4, send_event/3, stop/2, move_network/3]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-record(state, {
transport,
socket,
%%
is_registered = false,
%% ping的次数
ping_counter = 0,
%% id
packet_id = 1 :: integer(),
%%
inflight = #{}
}).
%%
-spec publish_command(Pid :: pid(), ReceiverPid :: pid(), CommandType :: integer(), Msg :: binary()) -> Ref :: reference().
publish_command(Pid, ReceiverPid, CommandType, Msg) when is_pid(Pid), is_pid(ReceiverPid), is_integer(CommandType), is_binary(Msg) ->
Ref = make_ref(),
Pid ! {publish_command, ReceiverPid, Ref, CommandType, Msg},
Ref.
%%
-spec move_network(Pid :: pid(), ReceiverPid :: pid(), NetworkPid :: pid()) -> Ref :: reference().
move_network(Pid, ReceiverPid, NetworkPid) when is_pid(Pid), is_pid(ReceiverPid), is_pid(NetworkPid) ->
Ref = make_ref(),
Pid ! {move_network, ReceiverPid, Ref, NetworkPid},
Ref.
%%
-spec send_event(Pid :: pid(), EventType :: integer(), Event :: binary()) -> no_return().
send_event(Pid, EventType, Event) when is_pid(Pid), is_integer(EventType), is_binary(Event) ->
Pid ! {send_event, EventType, Event}.
%%
-spec stop(Pid :: pid(), Reason :: any()) -> no_return().
stop(undefined, _Reason) ->
ok;
stop(Pid, Reason) when is_pid(Pid) ->
Pid ! {stop, Reason}.
%%--------------------------------------------------------------------
%% esockd callback
%%--------------------------------------------------------------------
start_link(Transport, Sock) ->
{ok, proc_lib:spawn_link(?MODULE, init, [[Transport, Sock]])}.
init([Transport, Sock]) ->
lager:debug("[sdlan_channel] get a new connection: ~p", [Sock]),
case Transport:wait(Sock) of
{ok, NewSock} ->
Transport:setopts(Sock, [{active, true}]),
erlang:start_timer(?PING_TICKER, self(), ping_ticker),
gen_server:enter_loop(?MODULE, [], #state{transport = Transport, socket = NewSock});
{error, Reason} ->
{stop, Reason}
end.
handle_call(_Request, _From, State) ->
{reply, ok, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
%%
handle_info({tcp, _Sock, <<Body/binary>>}, State = #state{is_registered = true}) ->
% #sdl_flows{forward_num = ForwardNum, p2p_num = P2PNum, inbound_num = InboundNum} = sdlan_pb:decode_msg(Body, sdl_flows),
lager:debug("[sdlan_channel] body: ~p", [Body]),
{noreply, State};
handle_info({tcp_error, Sock, Reason}, State = #state{socket = Sock}) ->
lager:notice("[sdlan_channel] tcp_error: ~p", [Reason]),
{stop, normal, State};
handle_info({tcp_closed, Sock}, State = #state{socket = Sock}) ->
lager:notice("[sdlan_channel] tcp_closed", []),
{stop, normal, State};
%%
handle_info({stop, Reason}, State) ->
{stop, Reason, State};
handle_info(Info, State) ->
lager:warning("[sdlan_channel] get a unknown message: ~p, channel will closed", [Info]),
{noreply, State}.
terminate(Reason, #state{}) ->
lager:warning("[sdlan_channel] stop with reason: ~p", [Reason]),
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% helper methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%