aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2016-05-17 20:55:45 +0200
committerHolger Weiss <holger@zedat.fu-berlin.de>2016-05-17 20:55:45 +0200
commit4f009e64fc11ca352443e6a9df5fa4d7cb715f5c (patch)
tree824bdf4424e3ec80a6a66d82eef0e3fa18ceba82
parentMove CSI queue handling into mod_client_state (diff)
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.
-rw-r--r--src/mod_client_state.erl30
-rw-r--r--test/ejabberd_SUITE.erl11
-rw-r--r--test/ejabberd_SUITE_data/ejabberd.yml4
3 files changed, 25 insertions, 20 deletions
diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl
index 7d23beb0d..f51a7fd24 100644
--- a/src/mod_client_state.erl
+++ b/src/mod_client_state.erl
@@ -44,10 +44,10 @@ start(Host, Opts) ->
QueuePresence = gen_mod:get_opt(queue_presence, Opts,
fun(B) when is_boolean(B) -> B end,
true),
- DropChatStates = gen_mod:get_opt(drop_chat_states, Opts,
- fun(B) when is_boolean(B) -> B end,
- true),
- if QueuePresence; DropChatStates ->
+ QueueChatStates = gen_mod:get_opt(queue_chat_states, Opts,
+ fun(B) when is_boolean(B) -> B end,
+ true),
+ if QueuePresence; QueueChatStates ->
ejabberd_hooks:add(c2s_post_auth_features, Host, ?MODULE,
add_stream_feature, 50),
if QueuePresence ->
@@ -55,7 +55,7 @@ start(Host, Opts) ->
filter_presence, 50);
true -> ok
end,
- if DropChatStates ->
+ if QueueChatStates ->
ejabberd_hooks:add(csi_filter_stanza, Host, ?MODULE,
filter_chat_states, 50);
true -> ok
@@ -71,10 +71,10 @@ stop(Host) ->
QueuePresence = gen_mod:get_module_opt(Host, ?MODULE, queue_presence,
fun(B) when is_boolean(B) -> B end,
true),
- DropChatStates = gen_mod:get_module_opt(Host, ?MODULE, drop_chat_states,
- fun(B) when is_boolean(B) -> B end,
- true),
- if QueuePresence; DropChatStates ->
+ QueueChatStates = gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states,
+ fun(B) when is_boolean(B) -> B end,
+ true),
+ if QueuePresence; QueueChatStates ->
ejabberd_hooks:delete(c2s_post_auth_features, Host, ?MODULE,
add_stream_feature, 50),
if QueuePresence ->
@@ -82,7 +82,7 @@ stop(Host) ->
filter_presence, 50);
true -> ok
end,
- if DropChatStates ->
+ if QueueChatStates ->
ejabberd_hooks:delete(csi_filter_stanza, Host, ?MODULE,
filter_chat_states, 50);
true -> ok
@@ -111,12 +111,12 @@ filter_presence({C2SState, _OutStanzas} = Acc, Host,
end;
filter_presence(Acc, _Host, _Stanza) -> Acc.
-filter_chat_states({C2SState, _OutStanzas} = Acc, _Host,
+filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
#xmlel{name = <<"message">>} = Stanza) ->
case jlib:is_standalone_chat_state(Stanza) of
- true -> % Drop the stanza.
+ true ->
?DEBUG("Got standalone chat state notification", []),
- {stop, {C2SState, []}};
+ queue_add(chatstate, Stanza, Host, C2SState);
false ->
Acc
end;
@@ -177,6 +177,6 @@ get_stanzas(Queue, Host) ->
mod_opt_type(queue_presence) ->
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;
-mod_opt_type(_) -> [queue_presence, drop_chat_states].
+mod_opt_type(_) -> [queue_presence, queue_chat_states].
diff --git a/test/ejabberd_SUITE.erl b/test/ejabberd_SUITE.erl
index aa465fb66..f3f7ebde3 100644
--- a/test/ejabberd_SUITE.erl
+++ b/test/ejabberd_SUITE.erl
@@ -2257,13 +2257,15 @@ client_state_master(Config) ->
Message = ChatState#message{body = [#text{data = <<"body">>}]},
%% Wait for the slave to become inactive.
wait_for_slave(Config),
- %% Should be dropped:
- send(Config, ChatState),
%% Should be queued (but see below):
send(Config, Presence),
%% Should replace the previous presence in the queue:
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),
%% Wait for the slave to become active.
wait_for_slave(Config),
@@ -2278,6 +2280,9 @@ client_state_slave(Config) ->
?recv1(#presence{from = Peer, type = unavailable,
sub_els = [#delay{}]}),
?recv1(#message{from = Peer, thread = <<"1">>,
+ sub_els = [#chatstate{type = composing},
+ #delay{}]}),
+ ?recv1(#message{from = Peer, thread = <<"1">>,
body = [#text{data = <<"body">>}],
sub_els = [#chatstate{type = active}]}),
change_client_state(Config, active),
diff --git a/test/ejabberd_SUITE_data/ejabberd.yml b/test/ejabberd_SUITE_data/ejabberd.yml
index 869c24c7a..30fff88fc 100644
--- a/test/ejabberd_SUITE_data/ejabberd.yml
+++ b/test/ejabberd_SUITE_data/ejabberd.yml
@@ -213,8 +213,8 @@ Welcome to this XMPP server."
db_type: internal
mod_carboncopy: []
mod_client_state:
- drop_chat_states: true
queue_presence: true
+ queue_chat_states: true
mod_adhoc: []
mod_configure: []
mod_disco: []
@@ -269,8 +269,8 @@ Welcome to this XMPP server."
db_type: internal
mod_carboncopy: []
mod_client_state:
- drop_chat_states: true
queue_presence: true
+ queue_chat_states: true
mod_adhoc: []
mod_configure: []
mod_disco: []