support client registry
This commit is contained in:
parent
8fa63244bb
commit
cd1e2c73d2
|
@ -123,7 +123,8 @@ handle_info(keep_alive_timeout, #state{keep_alive=KeepAlive}=State) ->
|
||||||
handle_info(Info, State) ->
|
handle_info(Info, State) ->
|
||||||
{stop, {badinfo, Info}, State}.
|
{stop, {badinfo, Info}, State}.
|
||||||
|
|
||||||
terminate(_Reason, #state{keep_alive=KeepAlive}) ->
|
terminate(_Reason, #state{client_id=ClientId, keep_alive=KeepAlive}) ->
|
||||||
|
ok = emqtt_registry:unregister(ClientId),
|
||||||
emqtt_keep_alive:cancel(KeepAlive),
|
emqtt_keep_alive:cancel(KeepAlive),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -201,6 +202,7 @@ process_request(?CONNECT,
|
||||||
?ERROR_MSG("MQTT login failed - no credentials"),
|
?ERROR_MSG("MQTT login failed - no credentials"),
|
||||||
{?CONNACK_CREDENTIALS, State};
|
{?CONNACK_CREDENTIALS, State};
|
||||||
true ->
|
true ->
|
||||||
|
ok = emqtt_registry:register(ClientId, self()),
|
||||||
KeepAlive = emqtt_keep_alive:new(AlivePeriod*1500, keep_alive_timeout),
|
KeepAlive = emqtt_keep_alive:new(AlivePeriod*1500, keep_alive_timeout),
|
||||||
{?CONNACK_ACCEPT,
|
{?CONNACK_ACCEPT,
|
||||||
State #state{ will_msg = make_will_msg(Var),
|
State #state{ will_msg = make_will_msg(Var),
|
||||||
|
@ -355,6 +357,7 @@ control_throttle(State = #state{ connection_state = Flow,
|
||||||
end.
|
end.
|
||||||
|
|
||||||
stop(Reason, State ) ->
|
stop(Reason, State ) ->
|
||||||
|
|
||||||
{stop, Reason, State}.
|
{stop, Reason, State}.
|
||||||
|
|
||||||
valid_client_id(ClientId) ->
|
valid_client_id(ClientId) ->
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
-module(emqtt_registry).
|
||||||
|
|
||||||
|
-include("emqtt.hrl").
|
||||||
|
|
||||||
|
-export([start_link/0,
|
||||||
|
size/0,
|
||||||
|
register/2,
|
||||||
|
unregister/1]).
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
|
|
||||||
|
-export([init/1,
|
||||||
|
handle_call/3,
|
||||||
|
handle_cast/2,
|
||||||
|
handle_info/2,
|
||||||
|
terminate/2,
|
||||||
|
code_change/3]).
|
||||||
|
|
||||||
|
-record(state, {}).
|
||||||
|
|
||||||
|
-define(SERVER, ?MODULE).
|
||||||
|
|
||||||
|
%%----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
start_link() ->
|
||||||
|
gen_server2:start_link({local, ?SERVER}, ?MODULE, [], []).
|
||||||
|
|
||||||
|
size() ->
|
||||||
|
ets:info(client, size).
|
||||||
|
|
||||||
|
register(ClientId, Pid) ->
|
||||||
|
gen_server2:cast(?SERVER, {register, ClientId, Pid}).
|
||||||
|
|
||||||
|
unregister(ClientId) ->
|
||||||
|
gen_server2:cast(?SERVER, {unregister, ClientId}).
|
||||||
|
|
||||||
|
%%----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
init([]) ->
|
||||||
|
ets:new(client, [set, protected, named_table]),
|
||||||
|
?INFO("~p is started.", [?MODULE]),
|
||||||
|
{ok, #state{}}. % clientid -> {pid, monitor}
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------------
|
||||||
|
handle_call(Req, _From, State) ->
|
||||||
|
{stop, {badreq, Req}, State}.
|
||||||
|
|
||||||
|
handle_cast({register, ClientId, Pid}, State) ->
|
||||||
|
?INFO("register ~p ~p", [ClientId, Pid]),
|
||||||
|
case ets:lookup(client, ClientId) of
|
||||||
|
[{_, {OldPid, MRef}}] ->
|
||||||
|
catch gen_server2:call(OldPid, duplicate_id),
|
||||||
|
erlang:demonitor(MRef);
|
||||||
|
[] ->
|
||||||
|
ignore
|
||||||
|
end,
|
||||||
|
ets:insert(client, {ClientId, {Pid, erlang:monitor(process, Pid)}}),
|
||||||
|
{noreply, State};
|
||||||
|
|
||||||
|
handle_cast({unregister, ClientId}, State) ->
|
||||||
|
?INFO("unregister ~p", [ClientId]),
|
||||||
|
case ets:lookup(client, ClientId) of
|
||||||
|
[{_, {_Pid, MRef}}] ->
|
||||||
|
erlang:demonitor(MRef),
|
||||||
|
ets:delete(client, ClientId);
|
||||||
|
[] ->
|
||||||
|
ignore
|
||||||
|
end,
|
||||||
|
{noreply, State};
|
||||||
|
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
{stop, {badmsg, Msg}, State}.
|
||||||
|
|
||||||
|
handle_info({'DOWN', MRef, process, DownPid, _Reason}, State) ->
|
||||||
|
ets:match_delete(client, {'_', {DownPid, MRef}}),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
terminate(_Reason, _State) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
{ok, State}.
|
||||||
|
|
|
@ -29,6 +29,7 @@ init([Listeners]) ->
|
||||||
?CHILD(emqtt_auth, worker),
|
?CHILD(emqtt_auth, worker),
|
||||||
?CHILD(emqtt_retained, worker),
|
?CHILD(emqtt_retained, worker),
|
||||||
?CHILD(emqtt_router, worker),
|
?CHILD(emqtt_router, worker),
|
||||||
|
?CHILD(emqtt_registry, worker),
|
||||||
?CHILD(emqtt_client_sup, supervisor)
|
?CHILD(emqtt_client_sup, supervisor)
|
||||||
| listener_children(Listeners) ]}
|
| listener_children(Listeners) ]}
|
||||||
}.
|
}.
|
||||||
|
|
Loading…
Reference in New Issue