From 3263578fb26f1b08087ed42fc9e627889c982894 Mon Sep 17 00:00:00 2001 From: Hans Svensson Date: Thu, 7 May 2020 16:13:52 +0200 Subject: [PATCH] Simplify unsubscribe_client When we the client disconnects we don't need to unsubscribe with finesse. --- apps/roster/src/protocol/roster_presence.erl | 11 +++---- apps/roster/src/roster.erl | 30 ++++++++++++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/apps/roster/src/protocol/roster_presence.erl b/apps/roster/src/protocol/roster_presence.erl index 7bfe3810b..80d7202ef 100644 --- a/apps/roster/src/protocol/roster_presence.erl +++ b/apps/roster/src/protocol/roster_presence.erl @@ -13,7 +13,6 @@ info(#'Presence'{status=Status} = RequestData, Req, #cx{params = ClientId, clien on_connect(Phone, ClientId, C)-> on_connect(Phone, ClientId, C, ?VERSION). on_connect(Phone, ClientId, C, Ver) -> ?LOG_INFO("~p:~p:CONNECT with Version:~p", [Phone, ClientId,Ver]), - catch n2o_vnode:unsubscribe(ClientId, iolist_to_binary(["actions/", "1", "/micro/", ClientId])), try case send_presence(online, Phone, C, ClientId) of {error, profile_not_found} -> ?LOG_INFO("~p:~p:Connect:ProfileNotFound", [Phone, ClientId]), @@ -28,19 +27,17 @@ on_connect(Phone, ClientId, C, Ver) -> ?LOG_INFO("Catch:~p", [n2o:stack_trace(Err, Rea)]) end. -on_disconnect(#'Auth'{type = logout, phone = Phone, client_id = ClientId, user_id = PhoneId}, C) -> +on_disconnect(#'Auth'{type = logout, phone = Phone, client_id = ClientId}, C) -> ?LOG_INFO("~p:~p:DISCONNECT:LOGOUT", [Phone, ClientId]), send_presence(offline, Phone, C, ClientId), - roster:unsubscribe_p2p(ClientId, roster:roster_id(PhoneId)), - roster:unsubscribe_room(ClientId), + roster:unsubscribe_client(ClientId), kvs:delete('Auth', ClientId), roster:final_disconnect(ClientId); -on_disconnect(#'Auth'{type = disconnect, phone = Phone, client_id = ClientId, user_id = PhoneId}, C) -> +on_disconnect(#'Auth'{type = disconnect, phone = Phone, client_id = ClientId}, C) -> ?LOG_INFO("~p:~p:DISCONNECT", [Phone, ClientId]), send_presence(offline, Phone, C, ClientId), - roster:unsubscribe_p2p(ClientId, roster:roster_id(PhoneId)), - roster:unsubscribe_room(ClientId), + roster:unsubscribe_client(ClientId), case should_preserve_auth_record(ClientId) of true -> ok; false -> kvs:delete('Auth', ClientId) diff --git a/apps/roster/src/roster.erl b/apps/roster/src/roster.erl index 72385a8a9..cc3e4f5bf 100644 --- a/apps/roster/src/roster.erl +++ b/apps/roster/src/roster.erl @@ -576,6 +576,11 @@ on_client_disconnected(_Reason, #mqtt_client{client_id = <<"emqttd_", _/bytes>> on_client_disconnected(_Reason, #mqtt_client{client_id = <<"reg_", _/bytes>> = ClientId} = Client, _) -> ?LOG_INFO("~p:MQTT_CLIENT DISCONNECT ~p",[ClientId, Client]), + unsubscribe_client(ClientId), + final_disconnect(ClientId); +on_client_disconnected(_Reason, #mqtt_client{client_id = <<"sys_", _/bytes>> = ClientId} = Client, _) -> + ?LOG_INFO("~p:MQTT_CLIENT DISCONNECT ~p",[ClientId, Client]), + unsubscribe_client(ClientId), final_disconnect(ClientId); on_client_disconnected(_Reason, #mqtt_client{client_id = ClientId} = Client, _Env) -> ?LOG_INFO("~p:MQTT_CLIENT DISCONNECT ~p",[ClientId, Client]), @@ -590,9 +595,8 @@ on_disconnect(<<"emqttd_", _/binary>> = ClientId) -> _ -> skip end, ok. + final_disconnect(ClientId) -> - % ?LOG_INFO("~p:ANY DISCONNECT",[RegClientId]), - n2o_vnode:unsubscribe(ClientId, roster:action_topic(ClientId)), case kvs:get(mqtt_session, ClientId) of {ok, #mqtt_session{sess_pid = SessionPid}} -> emqttd_session:destroy(SessionPid, ClientId), @@ -872,6 +876,28 @@ sub_client(Subscr, ClientId, PhoneId) when Subscr == subscribe; Subscr == unsubs [sub_muc(Subscr, PhoneId, #muc{name = Room}, [ClientId]) || #'Room'{id = Room} <- Rooms], ok. +%% When we are about to disconnect a client we don't need to unsubscribe with finesse, +%% just unsubscribe everything. +unsubscribe_client(ClientId) -> + UnSub = fun() -> unsubscribe_client_(ClientId) end, + case mnesia:is_transaction() of + true -> UnSub(); + false -> mnesia:transaction(UnSub) + end. + +unsubscribe_client_(ClientId) -> + Topics = [ T || {_, _, T} <- mnesia:wread(mqtt_subscription, ClientId) ], + mnesia:delete({mqtt_subscription, ClientId}), + lists:foreach( + fun(T) -> + mnesia:delete_object({mqtt_subscriber, T, ClientId}), + mnesia:delete({mqtt_subproperty, {T, ClientId}}), + case mnesia:read(mqtt_subscriber, T) of + [] -> emqttd_router:del_route(T); + _ -> ok + end + end, Topics). + feed_key(Type, From, To) -> case From < To of true -> {Type, From, To}; _ -> {Type, To, From} end. feed_key(#p2p{from = From, to = To}) -> feed_key(p2p, From, To); feed_key(#muc{} = Feed) -> Feed. -- GitLab