fix efka client
This commit is contained in:
parent
ad5f06be0e
commit
7f0cb1d027
@ -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}) ->
|
||||||
|
|||||||
@ -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};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user