fix efka client

This commit is contained in:
anlicheng 2025-05-09 10:53:13 +08:00
parent ad5f06be0e
commit 7f0cb1d027
2 changed files with 95 additions and 65 deletions

View File

@ -16,21 +16,11 @@
%% %%
%% %%
-define(PACKET_REGISTER, 16#00). -define(PACKET_REQUEST, 16#01).
%% %%
-define(PACKET_RESPONSE, 16#01). -define(PACKET_RESPONSE, 16#02).
%% %%
-define(PACKET_METRIC_DATA, 16#02). -define(PACKET_PUSH, 16#02).
%%
-define(PACKET_EVENT, 16#03).
%% efka获取自身的采集项
-define(PACKET_REQUEST_CONFIG, 16#04).
%% efka下发给微服务配置
-define(PACKET_PUSH_CONFIG, 16#10).
-define(PACKET_INVOKE, 16#11).
%% API %% API
-export([start_link/3]). -export([start_link/3]).
@ -73,9 +63,8 @@ request_config() ->
{ok, Config}; {ok, Config};
{response, Ref, {error, Reason}} -> {response, Ref, {error, Reason}} ->
{error, Reason} {error, Reason}
after after 5000 ->
?EFKA_REQUEST_TIMEOUT -> {error, timeout}
{error, timeout}
end. end.
-spec device_offline(DeviceUUID :: binary()) -> no_return(). -spec device_offline(DeviceUUID :: binary()) -> no_return().
@ -114,17 +103,21 @@ init([ServiceId, Host, Port]) ->
ok = gen_tcp:controlling_process(Socket, self()), ok = gen_tcp:controlling_process(Socket, self()),
PacketId = 1, PacketId = 1,
Packet = <<?PACKET_REGISTER:8, PacketId:32, ServiceId/binary>>, Register = #{<<"id">> => PacketId, <<"method">> => <<"register">>, <<"params">> => #{<<"service_id">> => ServiceId}},
ok = gen_tcp:send(Socket, Packet), Packet = jiffy:encode(Register, [force_utf8]),
ok = gen_tcp:send(Socket, <<?PACKET_REQUEST, Packet/binary>>),
lager:debug("[efka_client] will send packet: ~p", [Packet]), lager:debug("[efka_client] will send packet: ~p", [Packet]),
receive receive
{tcp, Socket, <<?PACKET_RESPONSE, PacketId:32, 1:8>>} -> {tcp, Socket, <<?PACKET_RESPONSE, Data/binary>>} ->
{ok, #state{packet_id = PacketId + 1, host = Host, port = Port, socket = Socket}}; case catch jiffy:decode(Data, [return_maps]) of
{tcp, Socket, <<?PACKET_RESPONSE, PacketId:32, 0:8, Error/binary>>} -> #{<<"id">> := PacketId, <<"result">> := <<"ok">>} ->
{stop, Error} {ok, #state{packet_id = PacketId + 1, host = Host, port = Port, socket = Socket}};
after #{<<"id">> := PacketId, <<"error">> := #{<<"code">> := Code, <<"message">> := Error}} ->
?EFKA_REQUEST_TIMEOUT -> {stop, {error, {Code, Error}}}
{stop, register_timeout} end
after 5000 ->
{stop, register_timeout}
end. end.
%% @private %% @private
@ -143,8 +136,9 @@ handle_call({controller_process, ControllerPid}, _From, State) ->
%% done %% done
handle_call({request_config, ReceiverPid}, _From, State = #state{socket = Socket, packet_id = PacketId, inflight = Inflight}) -> handle_call({request_config, ReceiverPid}, _From, State = #state{socket = Socket, packet_id = PacketId, inflight = Inflight}) ->
Packet = <<?PACKET_REQUEST_CONFIG:8, PacketId:32>>, RequestConfig = #{<<"id">> => PacketId, <<"method">> => <<"request_config">>},
ok = gen_tcp:send(Socket, Packet), Packet = jiffy:encode(RequestConfig, [force_utf8]),
ok = gen_tcp:send(Socket, <<?PACKET_REQUEST, Packet/binary>>),
Ref = make_ref(), Ref = make_ref(),
{reply, {ok, Ref}, State#state{packet_id = next_packet_id(PacketId), inflight = maps:put(PacketId, {Ref, ReceiverPid}, Inflight)}}. {reply, {ok, Ref}, State#state{packet_id = next_packet_id(PacketId), inflight = maps:put(PacketId, {Ref, ReceiverPid}, Inflight)}}.
@ -160,17 +154,33 @@ handle_cast({send_metric_data, DeviceUUID, Measurement, Tags, Fields}, State = #
%% Line Protocol实现数据的传输 %% Line Protocol实现数据的传输
Point = efka_point:new(Measurement, Tags, Fields, efka_util:timestamp()), Point = efka_point:new(Measurement, Tags, Fields, efka_util:timestamp()),
Body = efka_point:normalized(Point), Body = efka_point:normalized(Point),
Len = byte_size(DeviceUUID),
Packet = <<?PACKET_METRIC_DATA, Len:8, DeviceUUID/binary, Body/binary>>, MetricData = #{
ok = gen_tcp:send(Socket, Packet), <<"id">> => 0,
<<"method">> => <<"metric_data">>,
<<"params">> => #{
<<"device_uuid">> => DeviceUUID,
<<"metric">> => Body
}
},
Packet = jiffy:encode(MetricData, [force_utf8]),
ok = gen_tcp:send(Socket, <<?PACKET_REQUEST, Packet/binary>>),
{noreply, State}; {noreply, State};
%% done %% done
handle_cast({send_event, EventType, Params}, State = #state{socket = Socket}) -> handle_cast({send_event, EventType, Body}, State = #state{socket = Socket}) ->
Packet = <<?PACKET_EVENT:8, EventType:16, Params/binary>>, Event = #{
ok = gen_tcp:send(Socket, Packet), <<"id">> => 0,
<<"method">> => <<"event">>,
<<"params">> => #{
<<"event_type">> => EventType,
<<"body">> => Body
}
},
Packet = jiffy:encode(Event, [force_utf8]),
ok = gen_tcp:send(Socket, <<?PACKET_REQUEST, Packet/binary>>),
{noreply, State}; {noreply, State};
@ -185,41 +195,61 @@ handle_cast(_Info, State = #state{}) ->
{stop, Reason :: term(), NewState :: #state{}}). {stop, Reason :: term(), NewState :: #state{}}).
%% %%
handle_info({tcp, Socket, <<?PACKET_RESPONSE:8, PacketId:32, Message/binary>>}, State = #state{socket = Socket, inflight = Inflight}) -> handle_info({tcp, Socket, <<?PACKET_RESPONSE, Packet/binary>>}, State = #state{socket = Socket, inflight = Inflight}) ->
case maps:take(PacketId, Inflight) of case jiffy:decode(Packet, [return_maps]) of
error -> #{<<"id">> := Id, <<"result">> := Result} ->
{noreply, State}; case maps:take(Id, Inflight) of
{{Ref, ReceiverPid}, NInflight} -> error ->
case Message of {noreply, State};
<<1:8, Result/binary>> -> {{Ref, ReceiverPid}, NInflight} ->
ReceiverPid ! {response, Ref, {ok, Result}}; ReceiverPid ! {response, Ref, {ok, Result}},
<<0:8, Error/binary>> -> {noreply, State#state{inflight = NInflight}}
ReceiverPid ! {response, Ref, {error, Error}} end;
end, #{<<"id">> := Id, <<"error">> := #{<<"code">> := Code, <<"message">> := Message}} ->
{noreply, State#state{inflight = NInflight}} case maps:take(Id, Inflight) of
error ->
{noreply, State};
{{Ref, ReceiverPid}, NInflight} ->
ReceiverPid ! {response, Ref, {error, {Code, Message}}},
{noreply, State#state{inflight = NInflight}}
end
end; end;
%% efka推送的参数设置 %% efka推送的参数设置
handle_info({tcp, Socket, <<?PACKET_PUSH_CONFIG:8, PacketId:32, ConfigJson/binary>>}, State = #state{socket = Socket, controller_process = ControllerPid}) -> handle_info({tcp, Socket, <<?PACKET_PUSH, Packet/binary>>}, State = #state{socket = Socket, controller_process = ControllerPid}) ->
Message = case is_pid(ControllerPid) andalso is_process_alive(ControllerPid) of case jiffy:decode(Packet, [return_maps]) of
true -> #{<<"id">> := Id, <<"method">> := <<"push_config">>, <<"params">> := ConfigJson} ->
Ref = make_ref(), Ref = make_ref(),
ControllerPid ! {push_config, Ref, ConfigJson}, ControllerPid ! {push_config, Ref, ConfigJson},
receive Reply =
{push_config_reply, Ref, ok} -> receive
<<1:8>>; {push_config_reply, Ref, ok} ->
{push_config_reply, Ref, {error, Reason}} when is_binary(Reason) -> #{<<"id">> => Id, <<"result">> => <<"ok">>};
<<0:8, Reason/binary>> {push_config_reply, Ref, {error, Reason}} when is_binary(Reason) ->
after 5000 -> #{<<"id">> => Id, <<"error">> => #{<<"code">> => -1, <<"message">> => Reason}}
<<0:8, "服务执行超时"/utf8>> after 5000 ->
end; #{<<"id">> => Id, <<"error">> => #{<<"code">> => -2, <<"message">> => <<"timeout">>}}
false -> end,
<<0:8, "处理进程异常"/utf8>> Packet = jiffy:encode(Reply, [force_utf8]),
end, ok = gen_tcp:send(Socket, Packet),
Packet = <<?PACKET_RESPONSE:8, PacketId:32, Message/binary>>, {noreply, State};
ok = gen_tcp:send(Socket, Packet),
{noreply, State}; #{<<"id">> := Id, <<"method">> := <<"invoke">>, <<"params">> := #{<<"payload">> := Payload, <<"timeout">> := Timeout}} ->
Ref = make_ref(),
ControllerPid ! {invoke, Ref, Payload},
Reply =
receive
{invoke_reply, Ref, {ok, Result}} ->
#{<<"id">> => Id, <<"result">> => Result};
{invoke_reply, Ref, {error, Reason}} when is_binary(Reason) ->
#{<<"id">> => Id, <<"error">> => #{<<"code">> => -1, <<"message">> => Reason}}
after Timeout * 1000 ->
#{<<"id">> => Id, <<"error">> => #{<<"code">> => -2, <<"message">> => <<"invoke timeout">>}}
end,
Packet = jiffy:encode(Reply, [force_utf8]),
ok = gen_tcp:send(Socket, Packet),
{noreply, State}
end;
%% %%
handle_info({tcp, Socket, Packet}, State = #state{socket = Socket}) -> handle_info({tcp, Socket, Packet}, State = #state{socket = Socket}) ->

View File

@ -145,7 +145,7 @@ handle_info({tcp, Socket, <<?PACKET_REQUEST_CONFIG:8, PacketId:32>>}, State = #s
{noreply, State}; {noreply, State};
%% %%
handle_info({tcp, Socket, <<?PACKET_METRIC_DATA:8, Len:8, DeviceUUID:Len/binary, Data/binary>>}, State = #state{socket = Socket, service_pid = ServicePid, is_registered = true}) -> handle_info({tcp, Socket, <<?PACKET_METRIC_DATA:8, Len:16, DeviceUUID:Len/binary, Data/binary>>}, State = #state{socket = Socket, service_pid = ServicePid, is_registered = true}) ->
efka_service:metric_data(ServicePid, DeviceUUID, Data), efka_service:metric_data(ServicePid, DeviceUUID, Data),
{noreply, State}; {noreply, State};