I am using ejabberd-17.03 from source code on linux machine.
I created a temporary chatroom programatically from the the server using userA’s jid and send direct invitation to user B which he accepts and join the chatroom.
My use case is that two users A and B are in a chatroom exchange messages. If no user sends the other user any message for 30 seconds then the room sends a randomly selected message to these two users.
I have implemented this as follows:
start(_Host, _Opts) ->
ejabberd_hooks:add(user_send_packet, _Host, ?MODULE, myMessage, 95).
stop(_Host) ->
ejabberd_hooks:delete(user_send_packet, _Host, ?MODULE, myMessage,95).
depends(_Host, _Opts)->[{?MODULE,soft}].
mod_opt_type(_Option)->
ok.
myMessage({#message{from = From, to = To, body= Body} =Packet, C2SState}) ->
{UserA,UserB}=select_user(Packet),
PacketType=returnPacketType(Packet),
if
(PacketType==normal) ->
dosomething(),
{Timer_Result,Ref_or_Reason} = timer:apply_interval(30000, ?MODULE, func(), [Arguments]),
if
(Timer_Result == ok)->
ets:insert(ref_table, {Key, Ref_or_Reason});
(Timer_Result == error)->
io:format(" Could not delete user after timeout, Reason is ~p~n",[Ref_or_Reason])
end;
(PacketType==groupchat)->
do_something_else(),
{Timer_Result,Ref_or_Reason} = timer:apply_interval(30000, ?MODULE, func(), [Arguments]),
if
(Timer_Result == ok)->
replace_old_ref_with_new(Key, Ref_or_Reason, ref_table);
(Timer_Result == error)->
io:format(" Could not delete user after timeout, Reason is ~p~n",[Ref_or_Reason])
end
end
if
(somecondition()==true)->
delete_ref(Key, ref_table);
True->
do_nothing
end,
{Packet, C2SState}.
Now everything is working fine except the following case:
1.Chatroom is created and exchange of messages starts between A and B and the timer also starts at this point.
If the user who created the chat room goes offline say at time T(by minimising app and killing it from an android device) and comes back online ,the timer stop, as in the function scheduled to be called at the end of 30 seconds doesn’t gets called.(here comes back online is highlighted because if the user doesn’t comes online the timer works as expected, it is only when the user comes online again , the timer stops and no logs are generated).
But if online user sends any message now at this point at T then the whole periodic operation of randomly selecting messages and sending them to clients starts again pretty well and ends well.
But if the online user doesn’t send any message at this point of time T then the timer scheduled never gets called, the the user is kept on waiting.
If the user who got invited to the chatroom goes offline at time T2(say way as in 2) and comes online again then the timer remains active and works as expected.
So I changed the logging level of ejabberd to 5 and saw that offline messages to the offline and online again user is not getting delivered.even though mod_offline is enabled in ejabberd.yml.
Log :
#message{
id = <<>>,type = error,lang = <<"en">>,
from =
{jid,<<"fWiTvj973AB”>>,<<“example.com">>,<<"Smack">>,<<"fwitvj973ab”>>,
<<"example.com">>,<<"Smack">>},
to =
{jid,<<"ac5a6b8c-66b8-4da7-8b1a-0f3ecb1e5gfd”>>,
<<"conference.example.com">>,<<"cXWmOrqEESd”>>,
<<"ac5a6b8c-66b8-4da7-8b1a-0f3ecb1e5gfd">>,
<<"conference.example.com">>,<<"cXWmOrqEESd">>},
subject = [#text{lang = <<>>,data = <<>>}],
body = [#text{lang = <<>>,data = <<"\"cXWmOrqEESd\"">>}],
thread = undefined,
sub_els =
[{xmlel,<<"q">>,[{<<"xmlns">>,<<"ns:custom”>>}],[]},
#stanza_error{
type = cancel,code = 503,by = <<>>,
reason = 'service-unavailable',
text =
#text{lang = <<"en">>,data = <<"User session terminated">>},
sub_els = []}],
meta = #{}}
ejabberd.yml
###. ============
###' SHAPER RULES
shaper_rules:
## Maximum number of offline messages that users can have:
max_user_offline_messages:
- 5000: admin
- 100
###. =======
###' MODULES
##
## Modules enabled in all ejabberd virtual hosts.
##
modules:
mod_offline:
db_type: sql
access_max_user_messages: max_user_offline_messages
store_empty_body: unless_chat_state
Although I don’t need these offline messages to be delivered perfectly but I am getting tilted towards the thought that whether it can be the reason for stopping my timer(But I can’t understand that why does it only stops when the user who created the room goes offline and comes back and why not when the other user does this?).
Why is this timer getting stopped and how can I keep it running periodically?