mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Support pausing sessions (thanks to Stefan Strigler) (thanks to Stefan Strigler)
SVN Revision: 2223
This commit is contained in:
parent
222cabb745
commit
bb26498faf
@ -4,12 +4,12 @@
|
|||||||
%%% Purpose : Implements XMPP over BOSH (XEP-0205) (formerly known as
|
%%% Purpose : Implements XMPP over BOSH (XEP-0205) (formerly known as
|
||||||
%%% HTTP Binding)
|
%%% HTTP Binding)
|
||||||
%%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de>
|
%%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de>
|
||||||
%%% Id : $Id: ejabberd_http_bind.erl 278 2007-08-16 10:53:28Z sstrigler $
|
%%% Id : $Id: ejabberd_http_bind.erl 280 2007-08-16 13:25:41Z sstrigler $
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
-module(ejabberd_http_bind).
|
-module(ejabberd_http_bind).
|
||||||
-author('steve@zeank.in-berlin.de').
|
-author('steve@zeank.in-berlin.de').
|
||||||
-vsn('$Rev: 278 $').
|
-vsn('$Rev: 280 $').
|
||||||
|
|
||||||
-behaviour(gen_fsm).
|
-behaviour(gen_fsm).
|
||||||
|
|
||||||
@ -53,6 +53,7 @@
|
|||||||
last_poll,
|
last_poll,
|
||||||
ctime = 0,
|
ctime = 0,
|
||||||
timer,
|
timer,
|
||||||
|
pause=0,
|
||||||
req_list = [] % list of requests
|
req_list = [] % list of requests
|
||||||
}).
|
}).
|
||||||
|
|
||||||
@ -73,9 +74,12 @@
|
|||||||
-define(MAX_REQUESTS, 2). % number of simultaneous requests
|
-define(MAX_REQUESTS, 2). % number of simultaneous requests
|
||||||
-define(MIN_POLLING, 2000000). % don't poll faster than that or we will
|
-define(MIN_POLLING, 2000000). % don't poll faster than that or we will
|
||||||
% shoot you (time in µsec)
|
% shoot you (time in µsec)
|
||||||
-define(MAX_WAIT, 3600). % max num of secs to keep a request on hold
|
-define(MAX_WAIT, 3600). % max num of secs to keep a request on hold
|
||||||
-define(MAX_INACTIVITY, 30000). % msecs to wait before terminating
|
-define(MAX_INACTIVITY, 30000). % msecs to wait before terminating
|
||||||
% idle sessions
|
% idle sessions
|
||||||
|
-define(MAX_PAUSE, 120). % may num of sec a client is allowed to pause
|
||||||
|
% the session
|
||||||
|
|
||||||
-define(CT, {"Content-Type", "text/xml; charset=utf-8"}).
|
-define(CT, {"Content-Type", "text/xml; charset=utf-8"}).
|
||||||
-define(HEADER, [?CT]).
|
-define(HEADER, [?CT]).
|
||||||
|
|
||||||
@ -288,14 +292,19 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
RidAllow = case StateData#state.rid of
|
RidAllow = case StateData#state.rid of
|
||||||
none ->
|
none ->
|
||||||
%% first request - nothing saved so far
|
%% first request - nothing saved so far
|
||||||
true;
|
{true, 0};
|
||||||
OldRid ->
|
OldRid ->
|
||||||
?DEBUG("state.rid/cur rid: ~p/~p",
|
?DEBUG("state.rid/cur rid: ~p/~p",
|
||||||
[OldRid, Rid]),
|
[OldRid, Rid]),
|
||||||
if
|
if
|
||||||
(OldRid < Rid) and
|
(OldRid < Rid) and
|
||||||
(Rid =< (OldRid + Hold + 1)) ->
|
(Rid =< (OldRid + Hold + 1)) ->
|
||||||
true;
|
case xml:get_attr_s("pause", Attrs) of
|
||||||
|
Pause1 when Pause1 =< ?MAX_PAUSE ->
|
||||||
|
{true, Pause1};
|
||||||
|
_ ->
|
||||||
|
{true, 0}
|
||||||
|
end;
|
||||||
(Rid =< OldRid) and
|
(Rid =< OldRid) and
|
||||||
(Rid > OldRid - Hold - 1) ->
|
(Rid > OldRid - Hold - 1) ->
|
||||||
repeat;
|
repeat;
|
||||||
@ -309,7 +318,7 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
true;
|
true;
|
||||||
false ->
|
false ->
|
||||||
false;
|
false;
|
||||||
true ->
|
{true, _} ->
|
||||||
case StateData#state.key of
|
case StateData#state.key of
|
||||||
"" ->
|
"" ->
|
||||||
true;
|
true;
|
||||||
@ -360,7 +369,7 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
end,
|
end,
|
||||||
{reply, Reply, StateName,
|
{reply, Reply, StateName,
|
||||||
StateData#state{input = "cancel", last_poll = LastPoll}};
|
StateData#state{input = "cancel", last_poll = LastPoll}};
|
||||||
true ->
|
{true, Pause} ->
|
||||||
SaveKey = if
|
SaveKey = if
|
||||||
NewKey == "" ->
|
NewKey == "" ->
|
||||||
Key;
|
Key;
|
||||||
@ -380,11 +389,19 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
El#hbr.rid > (Rid - 1 - Hold)]
|
El#hbr.rid > (Rid - 1 - Hold)]
|
||||||
],
|
],
|
||||||
%% ?DEBUG("reqlist: ~p", [ReqList]),
|
%% ?DEBUG("reqlist: ~p", [ReqList]),
|
||||||
|
|
||||||
|
%% setup next timer
|
||||||
|
cancel_timer(StateData#state.timer),
|
||||||
|
if
|
||||||
|
Pause > 0 ->
|
||||||
|
Timer = erlang:start_timer(
|
||||||
|
Pause, self(), []);
|
||||||
|
true ->
|
||||||
|
Timer = erlang:start_timer(
|
||||||
|
?MAX_INACTIVITY, self(), [])
|
||||||
|
end,
|
||||||
case StateData#state.waiting_input of
|
case StateData#state.waiting_input of
|
||||||
false ->
|
false ->
|
||||||
cancel_timer(StateData#state.timer),
|
|
||||||
Timer = erlang:start_timer(
|
|
||||||
?MAX_INACTIVITY, self(), []),
|
|
||||||
Input = Payload ++ [StateData#state.input],
|
Input = Payload ++ [StateData#state.input],
|
||||||
Reply = ok,
|
Reply = ok,
|
||||||
{reply, Reply, StateName,
|
{reply, Reply, StateName,
|
||||||
@ -393,6 +410,7 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
key = SaveKey,
|
key = SaveKey,
|
||||||
ctime = TNow,
|
ctime = TNow,
|
||||||
timer = Timer,
|
timer = Timer,
|
||||||
|
pause = Pause,
|
||||||
last_poll = LastPoll,
|
last_poll = LastPoll,
|
||||||
req_list = ReqList
|
req_list = ReqList
|
||||||
}};
|
}};
|
||||||
@ -416,9 +434,6 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
?DEBUG("really sending now: ~s", [SendPacket]),
|
?DEBUG("really sending now: ~s", [SendPacket]),
|
||||||
Receiver ! {tcp, {http_bind, self()},
|
Receiver ! {tcp, {http_bind, self()},
|
||||||
list_to_binary(SendPacket)},
|
list_to_binary(SendPacket)},
|
||||||
cancel_timer(StateData#state.timer),
|
|
||||||
Timer = erlang:start_timer(
|
|
||||||
?MAX_INACTIVITY, self(), []),
|
|
||||||
Reply = ok,
|
Reply = ok,
|
||||||
{reply, Reply, StateName,
|
{reply, Reply, StateName,
|
||||||
StateData#state{waiting_input = false,
|
StateData#state{waiting_input = false,
|
||||||
@ -428,6 +443,7 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
key = SaveKey,
|
key = SaveKey,
|
||||||
ctime = TNow,
|
ctime = TNow,
|
||||||
timer = Timer,
|
timer = Timer,
|
||||||
|
pause = Pause,
|
||||||
last_poll = LastPoll,
|
last_poll = LastPoll,
|
||||||
req_list = ReqList
|
req_list = ReqList
|
||||||
}}
|
}}
|
||||||
@ -439,16 +455,26 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
handle_sync_event({http_get, Rid, Wait, Hold}, _From, StateName, StateData) ->
|
handle_sync_event({http_get, Rid, Wait, Hold}, _From, StateName, StateData) ->
|
||||||
|
%% setup timer
|
||||||
|
cancel_timer(StateData#state.timer),
|
||||||
|
if
|
||||||
|
StateData#state.pause > 0 ->
|
||||||
|
Timer = erlang:start_timer(
|
||||||
|
StateData#state.pause, self(), []);
|
||||||
|
true ->
|
||||||
|
Timer = erlang:start_timer(
|
||||||
|
?MAX_INACTIVITY, self(), [])
|
||||||
|
end,
|
||||||
|
|
||||||
{_,TSec,TMSec} = now(),
|
{_,TSec,TMSec} = now(),
|
||||||
TNow = TSec*1000*1000 + TMSec,
|
TNow = TSec*1000*1000 + TMSec,
|
||||||
cancel_timer(StateData#state.timer),
|
|
||||||
Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []),
|
|
||||||
if
|
if
|
||||||
(Hold > 0) and
|
(Hold > 0) and
|
||||||
(StateData#state.output == "") and
|
(StateData#state.output == "") and
|
||||||
((TNow - StateData#state.ctime) < (Wait*1000*1000)) and
|
((TNow - StateData#state.ctime) < (Wait*1000*1000)) and
|
||||||
(StateData#state.rid == Rid) and
|
(StateData#state.rid == Rid) and
|
||||||
(StateData#state.input /= "cancel") ->
|
(StateData#state.input /= "cancel") and
|
||||||
|
(StateData#state.pause == 0) ->
|
||||||
Output = StateData#state.output,
|
Output = StateData#state.output,
|
||||||
ReqList = StateData#state.req_list,
|
ReqList = StateData#state.req_list,
|
||||||
Reply = {ok, keep_on_hold};
|
Reply = {ok, keep_on_hold};
|
||||||
@ -678,6 +704,8 @@ prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold}=Sess,
|
|||||||
{"inactivity",
|
{"inactivity",
|
||||||
integer_to_list(
|
integer_to_list(
|
||||||
trunc(?MAX_INACTIVITY/1000))},
|
trunc(?MAX_INACTIVITY/1000))},
|
||||||
|
{"maxpause",
|
||||||
|
integer_to_list(?MAX_PAUSE)},
|
||||||
{"polling",
|
{"polling",
|
||||||
integer_to_list(
|
integer_to_list(
|
||||||
trunc(?MIN_POLLING/1000000))},
|
trunc(?MIN_POLLING/1000000))},
|
||||||
|
Loading…
Reference in New Issue
Block a user