diff --git a/apps/sdlan/src/quic/sdlan_quic_channel.erl b/apps/sdlan/src/quic/sdlan_quic_channel.erl index cc75ed3..68d5dda 100644 --- a/apps/sdlan/src/quic/sdlan_quic_channel.erl +++ b/apps/sdlan/src/quic/sdlan_quic_channel.erl @@ -49,7 +49,10 @@ mac :: undefined | binary(), ip = 0 :: integer(), - ping_counter = 0 + ping_counter = 0, + + %% 离线回调函数 + offline_cb :: undefined | fun() }). %%%=================================================================== @@ -179,9 +182,23 @@ handle_event(internal, {frame, <>}, initial %% 发送确认信息 quic_send(Stream, <>), %% 设置节点的在线状态 - Result = sdlan_api:node_online(ClientId, NetworkId, sdlan_ipaddr:int_to_ipv4(Ip)), + Result = sdlan_api:set_node_status(#{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"access_token">> => AccessToken, + <<"status">> => 1 + }), logger:debug("[sdlan_quic_channel] client_id: ~p, set none online result is: ~p", [ClientId, Result]), - {next_state, registered, State#state{network_id = NetworkId, network_pid = NetworkPid, client_id = ClientId, mac = Mac, ip = Ip}}; + + OfflineCb = fun() -> + Result = sdlan_api:set_node_status(#{ + <<"network_id">> => NetworkId, + <<"client_id">> => ClientId, + <<"access_token">> => AccessToken, + <<"status">> => 0 + }) + end, + {next_state, registered, State#state{network_id = NetworkId, network_pid = NetworkPid, client_id = ClientId, mac = Mac, ip = Ip, offline_cb = OfflineCb}}; undefined -> logger:warning("[sdlan_quic_channel] client_id: ~p, register get error: network not found", [ClientId]), quic_send(Stream, register_nak_reply(PktId, ?NAK_INTERNAL_FAULT, <<"Internal Error">>)), @@ -284,10 +301,12 @@ handle_event(EventType, Info, StateName, State) -> %% terminate. It should be the opposite of Module:init/1 and do any %% necessary cleaning up. When it returns, the gen_statem terminates with %% Reason. The return value is ignored. -terminate(Reason, _StateName, _State = #state{conn = Conn, stream = Stream}) -> +terminate(Reason, _StateName, _State = #state{conn = Conn, stream = Stream, offline_cb = OfflineCb}) -> Stream /= undefined andalso quicer:close_stream(Stream), quicer:close_connection(Conn), logger:warning("[sdlan_quic_conn] terminate closed with reason: ~p", [Reason]), + %% 触发客户端的离线逻辑 + is_function(OfflineCb) andalso OfflineCb(), ok. %% @private diff --git a/apps/sdlan/src/sdlan_api.erl b/apps/sdlan/src/sdlan_api.erl index 89ce7b6..dad76ea 100644 --- a/apps/sdlan/src/sdlan_api.erl +++ b/apps/sdlan/src/sdlan_api.erl @@ -13,7 +13,7 @@ %% API -export([get_all_networks/0, get_network/1]). --export([node_online/3, node_offline/2, flow_report/5, network_forward_report/2, auth_access_token/1]). +-export([flow_report/5, network_forward_report/2, auth_access_token/1, set_node_status/1]). -spec get_all_networks() -> {ok, [NetworkId :: integer()]} | {error, Reason :: any()}. get_all_networks() -> @@ -61,18 +61,9 @@ auth_access_token(Params) when is_map(Params) -> Error end. --spec node_online(ClientId :: binary(), NetworkId :: integer(), IpAddr :: binary()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -node_online(ClientId, NetworkId, IpAddr) when is_binary(ClientId), is_integer(NetworkId), is_binary(IpAddr) -> - case catch do_post("set_node_status", #{<<"client_id">> => ClientId, <<"network_id">> => NetworkId, <<"ip_addr">> => IpAddr, <<"status">> => 1}) of - {ok, Resp} -> - {ok, catch jiffy:decode(Resp, [return_maps])}; - Error -> - Error - end. - --spec node_offline(ClientId :: binary(), NetworkId :: integer()) -> {ok, Resp :: map()} | {error, Reason :: any()}. -node_offline(ClientId, NetworkId) when is_binary(ClientId), is_integer(NetworkId) -> - case catch do_post("set_node_status", #{<<"client_id">> => ClientId, <<"network_id">> => NetworkId, <<"status">> => 0}) of +-spec set_node_status(Params :: map()) -> {ok, Resp :: map()} | {error, Reason :: any()}. +set_node_status(Params) when is_map(Params) -> + case catch do_post("set_node_status", Params) of {ok, Resp} -> {ok, catch jiffy:decode(Resp, [return_maps])}; Error ->