PageRenderTime 35ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/ucengine/src/controllers/async/uce_async_stream.erl

http://github.com/AF83/ucengine
Erlang | 104 lines | 61 code | 16 blank | 27 comment | 0 complexity | afd1eda044bc426c96a49db1ace6d46f MD5 | raw file
  1. %%
  2. %% U.C.Engine - Unified Collaboration Engine
  3. %% Copyright (C) 2011 af83
  4. %%
  5. %% This program is free software: you can redistribute it and/or modify
  6. %% it under the terms of the GNU Affero General Public License as published by
  7. %% the Free Software Foundation, either version 3 of the License, or
  8. %% (at your option) any later version.
  9. %%
  10. %% This program is distributed in the hope that it will be useful,
  11. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. %% GNU Affero General Public License for more details.
  14. %%
  15. %% You should have received a copy of the GNU Affero General Public License
  16. %% along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. %%
  18. -module(uce_async_stream).
  19. -export([wait/9]).
  20. -include("uce.hrl").
  21. -behaviour(gen_server).
  22. -export([init/1,
  23. code_change/3,
  24. handle_call/3,
  25. handle_cast/2,
  26. handle_info/2,
  27. terminate/2]).
  28. %
  29. % Public API
  30. %
  31. wait(Domain, Uid, Location, Search, From, Types, Parent, Sid, PreviousEvents) ->
  32. YawsPid = self(),
  33. {ok, _Pid} = gen_server:start_link(?MODULE, [YawsPid, Domain, Uid, Location, Search, From, Types, Parent, Sid, PreviousEvents], []),
  34. {streamcontent_with_timeout, "text/event-stream", <<>>, infinity}.
  35. %
  36. % gen_server callbacks
  37. %
  38. init([YawsPid, Domain, Uid, Location, Search, From, Types, Parent, Sid, PreviousEvents]) ->
  39. process_flag(trap_exit, true),
  40. link(YawsPid),
  41. send_events(YawsPid, Domain, PreviousEvents),
  42. uce_meeting:subscribe(self(), Domain, Uid, Location, From, Types, Parent),
  43. uce_presence:add_stream(Domain, Sid),
  44. ping(),
  45. {ok, {YawsPid,
  46. Domain,
  47. Search,
  48. Sid}}.
  49. handle_call(_ , _, State) ->
  50. {reply, ok, State}.
  51. handle_cast(_, State) ->
  52. {noreply, State}.
  53. code_change(_, State,_) ->
  54. {ok, State}.
  55. handle_info({event, Event}, {YawsPid, Domain, Search, _Sid} = State) ->
  56. case uce_async:filter(Search, Event) of
  57. false ->
  58. ok;
  59. true ->
  60. send_events(YawsPid, Domain, [Event])
  61. end,
  62. {noreply, State};
  63. handle_info(ping, {YawsPid, _Domain, _Search, _Sid} = State) ->
  64. yaws_api:stream_chunk_deliver(YawsPid, ":\n\n"),
  65. ping(),
  66. {noreply, State};
  67. handle_info(Event, State) ->
  68. ?ERROR_MSG("unexpected ~p", [Event]),
  69. {noreply, State}.
  70. terminate(_Reason, {_, Domain, _, Sid}) ->
  71. uce_meeting:unsubscribe(self()),
  72. uce_presence:remove_stream(Domain, Sid),
  73. ok.
  74. %
  75. % Private API
  76. %
  77. ping() ->
  78. %% Send a PING command every 15s
  79. erlang:send_after(15000, self(), ping).
  80. send_events(_, _, []) ->
  81. ok;
  82. send_events(YawsPid, Domain, [#uce_event{datetime=Datetime} = Event|Events]) ->
  83. yaws_api:stream_chunk_deliver(YawsPid, "data: "),
  84. yaws_api:stream_chunk_deliver(YawsPid, mochijson:encode(json_helpers:to_json(Domain, Event))),
  85. yaws_api:stream_chunk_deliver(YawsPid, "\nid: "),
  86. yaws_api:stream_chunk_deliver(YawsPid, integer_to_list(Datetime)),
  87. yaws_api:stream_chunk_deliver(YawsPid, "\n\n"),
  88. send_events(YawsPid, Domain, Events).