emqx私有tcp协议服务器开发---emqx_tcp_connection模块(3)

 %% 回调处理
handle({call, From}, info, State) -> reply(From, info(State), State);
handle({call, From}, stats, State) -> reply(From, stats(State), State);
  
handle({call, From}, kick, State) ->
    ok = gen_statem:reply(From, ok),
    shutdown(kicked, State);
handle({call, From}, Req, State) ->
    begin
        logger:log(error,#{}, #{report_cb =>
             fun (_) ->{'$logger_header'() ++ "Unexpected call: ~p",[Req]} end,       
                  mfa => {emqx_tcp_connection, handle, 3}, line => 261})  
    end,                            
    reply(From, ignored, State);                            
                       
handle(cast, Msg, State) ->
    begin
        logger:log(error,#{}, #{report_cb => fun (_) ->
                  {'$logger_header'() ++ "Unexpected cast: ~p", [Msg]} end,
                   mfa => {emqx_tcp_connection, handle, 3}, line => 266}) end,
    {keep_state, State};        

handle(info, {Inet, _Sock, Data},State = #state{pstate = PState})
       
    when Inet == tcp; Inet == ssl ->
    Oct = iolist_size(Data),
    begin
        logger:log(debug, #{},#{report_cb =>
                  fun (_) -> {'$logger_header'() ++ "RECV ~p", [Data]} end,
                  mfa => {emqx_tcp_connection, handle, 3}, line => 273})
    end,
    %% 计算进来的数据包个数                 
    emqx_pd:inc_counter(incoming_bytes, Oct),
    %% 计算接收了多少个字节数据
    ok = emqx_metrics:inc('bytes.received', Oct),
    %% 检出虚拟机,除非gc从操作
    NPState = emqx_tcp_protocol:maybe_gc_and_check_oom(Oct,PState),
    %% 处理数据包                                                   
    process_incoming(Data, [],State#state{pstate = NPState});                     
                    
%% 错误处理         
handle(info, {Error, _Sock, Reason}, State)
    when Error == tcp_error; Error == ssl_error ->
    shutdown(Reason, State);
%% 关闭处理
handle(info, {Closed, _Sock}, State)
    when Closed == tcp_closed; Closed == ssl_closed ->
    shutdown(closed, State);
%%
handle(info, {Passive, _Sock}, State)
    when Passive == tcp_passive; Passive == ssl_passive ->
    NState = ensure_rate_limit(State),
    ok = activate_socket(NState),
    {keep_state, NState};
%% 设置
handle(info, activate_socket, State) ->
    ok = activate_socket(State#state{sockstate = running}),
    {keep_state,State#state{sockstate = running, limit_timer = undefined}};
     
                
handle(info, {inet_reply, _Sock, ok}, State) -> {keep_state, State};
   
handle(info, {inet_reply, _Sock, {error, Reason}}, State) ->shutdown(Reason, State);
  %% 超时处理       
handle(info, {timeout, Timer, emit_stats},
       State = #state{stats_timer = Timer, pstate = PState}) ->
    ClientId = emqx_tcp_protocol:client_id(PState),
    %% 设置客户端状态
    emqx_cm:set_chan_stats(ClientId, stats(State)),
    %% 统计定时停止
    {keep_state,ensure_stats_timer(State#state{stats_timer = undefined})};
     
                                        
handle(info, {timeout, _Ref, {keepalive, check}},
    State = #state{transport = Transport, socket = Socket,keepalive = Keepalive}) ->
                
    case Transport:getstat(Socket, [recv_oct]) of
        {ok, [{recv_oct, RecvOct}]} ->
            case emqx_keepalive:check(RecvOct, Keepalive) of
                {ok, NKeepalive} ->
                    {keep_state, State#state{keepalive = NKeepalive}};
                {error, timeout} -> shutdown(keepalive_timeout, State)
            end;
        {error, Reason} -> shutdown({sockerr, Reason}, State)
    end;

handle(info, {shutdown, discard, {ClientId, ByPid}},State) ->
       
    begin
        logger:log(error,#{}, #{report_cb =>fun (_) ->
               {'$logger_header'() ++ "Discarded by ~s:~p", [ClientId, ByPid]} end,
                mfa => {emqx_tcp_connection, handle, 3}, line => 329})                                       
    end,                              
    shutdown(discard, State);                    
%% 冲突处理
handle(info, {shutdown, conflict, {ClientId, NewPid}},State) ->
       
    begin
        logger:log(warning,#{}, #{report_cb => fun (_) ->
                   {'$logger_header'() ++"Clientid '~s' conflict with ~p",
                                       [ClientId, NewPid]}  end,
                   mfa => {emqx_tcp_connection, handle, 3}, line => 333})
     end,                    
     shutdown(conflict, State);                            

handle(info, {shutdown, Reason}, State) ->shutdown(Reason, State);
    
handle(info, Info, State) ->
    begin
        logger:log(error,#{},#{report_cb =>fun (_) ->
                 {'$logger_header'() ++ "Unexpected info: ~p",[Info]} end,
                  mfa => {emqx_tcp_connection, handle, 3}, line => 340})                
         
    end,
    {keep_state, State}.

code_change(_Vsn, State, Data, _Extra) ->
    {ok, State, Data}.

%% 终止进程
terminate(Reason, _StateName,#state{transport = Transport, socket = Socket,
           pstate = PState}) ->
                
    begin
        logger:log(debug, #{},#{report_cb =>fun (_) ->
                   {'$logger_header'() ++ "Terminated for ~p",[Reason]} end,
                    mfa => {emqx_tcp_connection, terminate, 3}, line => 349})             
    end,
    %% 快速关闭                              
    Transport:fast_close(Socket),                    
    %% 关闭原因处理
    case {PState, Reason} of
        {undefined, _} -> ok;
        {_, {shutdown, Error}} ->
            emqx_tcp_protocol:terminate(Error, PState);
        {_, Reason} ->
            emqx_tcp_protocol:terminate(Reason, PState)
    end.

猜你喜欢

转载自blog.csdn.net/qq513036862/article/details/110311205