25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-24 16:23:40 +01:00

mod_client_state: Queue chat state notifications

Queue standalone chat states instead of simply dropping them when the
client is inactive.  Only the most recent chat state of a given client
is queued.
This commit is contained in:
Holger Weiss 2016-05-17 20:55:45 +02:00
parent ba74c1c367
commit 4f009e64fc
3 changed files with 25 additions and 20 deletions

View File

@ -44,10 +44,10 @@ start(Host, Opts) ->
QueuePresence = gen_mod:get_opt(queue_presence, Opts, QueuePresence = gen_mod:get_opt(queue_presence, Opts,
fun(B) when is_boolean(B) -> B end, fun(B) when is_boolean(B) -> B end,
true), true),
DropChatStates = gen_mod:get_opt(drop_chat_states, Opts, QueueChatStates = gen_mod:get_opt(queue_chat_states, Opts,
fun(B) when is_boolean(B) -> B end, fun(B) when is_boolean(B) -> B end,
true), true),
if QueuePresence; DropChatStates -> if QueuePresence; QueueChatStates ->
ejabberd_hooks:add(c2s_post_auth_features, Host, ?MODULE, ejabberd_hooks:add(c2s_post_auth_features, Host, ?MODULE,
add_stream_feature, 50), add_stream_feature, 50),
if QueuePresence -> if QueuePresence ->
@ -55,7 +55,7 @@ start(Host, Opts) ->
filter_presence, 50); filter_presence, 50);
true -> ok true -> ok
end, end,
if DropChatStates -> if QueueChatStates ->
ejabberd_hooks:add(csi_filter_stanza, Host, ?MODULE, ejabberd_hooks:add(csi_filter_stanza, Host, ?MODULE,
filter_chat_states, 50); filter_chat_states, 50);
true -> ok true -> ok
@ -71,10 +71,10 @@ stop(Host) ->
QueuePresence = gen_mod:get_module_opt(Host, ?MODULE, queue_presence, QueuePresence = gen_mod:get_module_opt(Host, ?MODULE, queue_presence,
fun(B) when is_boolean(B) -> B end, fun(B) when is_boolean(B) -> B end,
true), true),
DropChatStates = gen_mod:get_module_opt(Host, ?MODULE, drop_chat_states, QueueChatStates = gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states,
fun(B) when is_boolean(B) -> B end, fun(B) when is_boolean(B) -> B end,
true), true),
if QueuePresence; DropChatStates -> if QueuePresence; QueueChatStates ->
ejabberd_hooks:delete(c2s_post_auth_features, Host, ?MODULE, ejabberd_hooks:delete(c2s_post_auth_features, Host, ?MODULE,
add_stream_feature, 50), add_stream_feature, 50),
if QueuePresence -> if QueuePresence ->
@ -82,7 +82,7 @@ stop(Host) ->
filter_presence, 50); filter_presence, 50);
true -> ok true -> ok
end, end,
if DropChatStates -> if QueueChatStates ->
ejabberd_hooks:delete(csi_filter_stanza, Host, ?MODULE, ejabberd_hooks:delete(csi_filter_stanza, Host, ?MODULE,
filter_chat_states, 50); filter_chat_states, 50);
true -> ok true -> ok
@ -111,12 +111,12 @@ filter_presence({C2SState, _OutStanzas} = Acc, Host,
end; end;
filter_presence(Acc, _Host, _Stanza) -> Acc. filter_presence(Acc, _Host, _Stanza) -> Acc.
filter_chat_states({C2SState, _OutStanzas} = Acc, _Host, filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
#xmlel{name = <<"message">>} = Stanza) -> #xmlel{name = <<"message">>} = Stanza) ->
case jlib:is_standalone_chat_state(Stanza) of case jlib:is_standalone_chat_state(Stanza) of
true -> % Drop the stanza. true ->
?DEBUG("Got standalone chat state notification", []), ?DEBUG("Got standalone chat state notification", []),
{stop, {C2SState, []}}; queue_add(chatstate, Stanza, Host, C2SState);
false -> false ->
Acc Acc
end; end;
@ -177,6 +177,6 @@ get_stanzas(Queue, Host) ->
mod_opt_type(queue_presence) -> mod_opt_type(queue_presence) ->
fun(B) when is_boolean(B) -> B end; fun(B) when is_boolean(B) -> B end;
mod_opt_type(drop_chat_states) -> mod_opt_type(queue_chat_states) ->
fun(B) when is_boolean(B) -> B end; fun(B) when is_boolean(B) -> B end;
mod_opt_type(_) -> [queue_presence, drop_chat_states]. mod_opt_type(_) -> [queue_presence, queue_chat_states].

View File

@ -2257,13 +2257,15 @@ client_state_master(Config) ->
Message = ChatState#message{body = [#text{data = <<"body">>}]}, Message = ChatState#message{body = [#text{data = <<"body">>}]},
%% Wait for the slave to become inactive. %% Wait for the slave to become inactive.
wait_for_slave(Config), wait_for_slave(Config),
%% Should be dropped:
send(Config, ChatState),
%% Should be queued (but see below): %% Should be queued (but see below):
send(Config, Presence), send(Config, Presence),
%% Should replace the previous presence in the queue: %% Should replace the previous presence in the queue:
send(Config, Presence#presence{type = unavailable}), send(Config, Presence#presence{type = unavailable}),
%% Should be sent immediately, together with the previous presence: %% Should be queued (but see below):
send(Config, ChatState),
%% Should replace the previous chat state in the queue:
send(Config, ChatState#message{sub_els = [#chatstate{type = composing}]}),
%% Should be sent immediately, together with the queued stanzas:
send(Config, Message), send(Config, Message),
%% Wait for the slave to become active. %% Wait for the slave to become active.
wait_for_slave(Config), wait_for_slave(Config),
@ -2277,6 +2279,9 @@ client_state_slave(Config) ->
wait_for_master(Config), wait_for_master(Config),
?recv1(#presence{from = Peer, type = unavailable, ?recv1(#presence{from = Peer, type = unavailable,
sub_els = [#delay{}]}), sub_els = [#delay{}]}),
?recv1(#message{from = Peer, thread = <<"1">>,
sub_els = [#chatstate{type = composing},
#delay{}]}),
?recv1(#message{from = Peer, thread = <<"1">>, ?recv1(#message{from = Peer, thread = <<"1">>,
body = [#text{data = <<"body">>}], body = [#text{data = <<"body">>}],
sub_els = [#chatstate{type = active}]}), sub_els = [#chatstate{type = active}]}),

View File

@ -213,8 +213,8 @@ Welcome to this XMPP server."
db_type: internal db_type: internal
mod_carboncopy: [] mod_carboncopy: []
mod_client_state: mod_client_state:
drop_chat_states: true
queue_presence: true queue_presence: true
queue_chat_states: true
mod_adhoc: [] mod_adhoc: []
mod_configure: [] mod_configure: []
mod_disco: [] mod_disco: []
@ -269,8 +269,8 @@ Welcome to this XMPP server."
db_type: internal db_type: internal
mod_carboncopy: [] mod_carboncopy: []
mod_client_state: mod_client_state:
drop_chat_states: true
queue_presence: true queue_presence: true
queue_chat_states: true
mod_adhoc: [] mod_adhoc: []
mod_configure: [] mod_configure: []
mod_disco: [] mod_disco: []