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

%% 获取进程状态                        
info(PState) ->
    maps:from_list(info([conninfo,conn_state,clientinfo,session,will_msg],PState)).
                         
info(Keys, PState) when is_list(Keys) ->[{Key, info(Key, PState)} || Key <- Keys];
%% 连接状态   
info(conninfo, PState) -> conninfo(PState);
%% 客户信息
info(clientinfo, PState) -> clientinfo(PState);
%% session信息
info(session, _) -> undefined;
%% 连接状态
info(conn_state, #pstate{connected = Connected}) ->Connected;
%% 意愿消息
info(will_msg, _) -> undefined.
%% 客户端id
client_id(#pstate{client_id = ClientId}) -> ClientId.
%% 统计数据
stats(#pstate{recv_stats = #{pkt := RecvPkt, msg := RecvMsg},send_stats = #{pkt := SendPkt, msg := SendMsg}}) ->
    [{recv_pkt, RecvPkt},{recv_msg, RecvMsg},{send_pkt, SendPkt},{send_msg, SendMsg}].
    
start_keepalive(0, _PState) -> ignore;
start_keepalive(Secs, _PState) when Secs > 0 ->
    self() ! {keepalive, start, round(Secs)}.

clientinfo(#pstate{client_id = ClientId,
                   username = Username, peername = {Peerhost, _},peercert = Peercert}) ->
                   
    with_cert(#{zone => undefined, protocol => tcp,
                peerhost => Peerhost, clientid => ClientId,
                username => Username, peercert => Peercert,
                is_bridge => false, is_supuser => false,
                mountpoint => undefined, ws_cookie => undefined,
                sockport => 8090},
              Peercert).

with_cert(ClientInfo, undefined) -> ClientInfo;
with_cert(ClientInfo, Peercert) ->
    ClientInfo#{dn => esockd_peercert:subject(Peercert),
                cn => esockd_peercert:common_name(Peercert)}.

conninfo(#pstate{sockname = Sockname,
                 peername = Peername, peercert = Peercert,
                 client_id = ClientId, username = Username,
                 keepalive = Keepalive, connected = Connected,
                 connected_at = ConnectedAt, conn_mod = ConnMod,
                 proto_ver = ProtoVer}) ->
    #{socktype => tcp, sockname => Sockname,
      peername => Peername, peercert => Peercert,
      conn_mod => ConnMod, proto_name => <<"tcp">>,
      proto_ver => ProtoVer, clean_start => true,
      clientid => ClientId, username => Username,
      conn_props => [], connected => Connected,
      connected_at => ConnectedAt, keepalive => Keepalive,
      receive_maximum => 0, expiry_interval => 0}.

prepare_adapter_topic(PState = #pstate{up_topic = UpTopic,dn_topic = DnTopic}) ->                     
    PState#pstate{up_topic = replvar(UpTopic, PState),dn_topic = replvar(DnTopic, PState)}.
                  

replvar(undefined, _PState) -> undefined;
replvar(Topic,#pstate{client_id = ClientId, username = Username}) ->
    iolist_to_binary(re:replace(re:replace(Topic,"%c",ClientId),"%u", to_binary(Username))).
                         
autosubcribe(#pstate{dn_topic = Topic})when Topic == undefined; Topic == "" ->ok;
    
autosubcribe(PState = #pstate{dn_topic = Topic,client_id = ClientId}) ->
    SubOpts = #{rap => 0, nl => 0, qos => 0, rh => 0},              
    emqx:subscribe(Topic, ClientId, SubOpts),
    ok = emqx_hooks:run('session.subscribed',[clientinfo(PState), Topic, SubOpts#{is_new => true}]).
                        

connack({0, PState}) ->
    _ = run_hooks('client.connack',[conninfo(PState), success],undefined),           
    run_hooks('client.connected',[clientinfo(PState), conninfo(PState)]),
    deliver({connack, 0, <<"Connect Successfully">>},PState);
            
connack({Code, Msg, PState}) ->
    _ = run_hooks('client.connack',[conninfo(PState), not_authorized],undefined),             
    deliver({connack, Code, Msg}, PState).

do_publish(#tcp_packet_datatrans{data = Data},PState = #pstate{up_topic = Topic}) ->  
    Msg = emqx_message:make(emqx_tcp_connector,Topic,Data),    
    emqx:publish(Msg),
    {ok, PState}.

猜你喜欢

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