PageRenderTime 123ms CodeModel.GetById 60ms app.highlight 12ms RepoModel.GetById 49ms 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
 20-export([wait/9]).
 21
 22-include("uce.hrl").
 23
 24-behaviour(gen_server).
 25
 26-export([init/1,
 27         code_change/3,
 28         handle_call/3,
 29         handle_cast/2,
 30         handle_info/2,
 31         terminate/2]).
 32
 33%
 34% Public API
 35%
 36
 37wait(Domain, Uid, Location, Search, From, Types, Parent, Sid, PreviousEvents) ->
 38    YawsPid = self(),
 39    {ok, _Pid} = gen_server:start_link(?MODULE, [YawsPid, Domain, Uid, Location, Search, From, Types, Parent, Sid, PreviousEvents], []),
 40    {streamcontent_with_timeout, "text/event-stream", <<>>, infinity}.
 41
 42%
 43% gen_server callbacks
 44%
 45
 46init([YawsPid, Domain, Uid, Location, Search, From, Types, Parent, Sid, PreviousEvents]) ->
 47    process_flag(trap_exit, true),
 48    link(YawsPid),
 49    send_events(YawsPid, Domain, PreviousEvents),
 50    uce_meeting:subscribe(self(), Domain, Uid, Location, From, Types, Parent),
 51    uce_presence:add_stream(Domain, Sid),
 52    ping(),
 53    {ok, {YawsPid,
 54          Domain,
 55          Search,
 56          Sid}}.
 57
 58handle_call(_ , _, State) ->
 59    {reply, ok, State}.
 60
 61handle_cast(_, State) ->
 62    {noreply, State}.
 63
 64code_change(_, State,_) ->
 65    {ok, State}.
 66
 67handle_info({event, Event}, {YawsPid, Domain, Search, _Sid} = State) ->
 68    case uce_async:filter(Search, Event) of
 69        false ->
 70            ok;
 71        true ->
 72            send_events(YawsPid, Domain, [Event])
 73    end,
 74    {noreply, State};
 75handle_info(ping, {YawsPid, _Domain, _Search, _Sid} = State) ->
 76    yaws_api:stream_chunk_deliver(YawsPid, ":\n\n"),
 77    ping(),
 78    {noreply, State};
 79handle_info(Event, State) ->
 80    ?ERROR_MSG("unexpected ~p", [Event]),
 81    {noreply, State}.
 82
 83terminate(_Reason, {_, Domain, _, Sid}) ->
 84    uce_meeting:unsubscribe(self()),
 85    uce_presence:remove_stream(Domain, Sid),
 86    ok.
 87
 88%
 89% Private API
 90%
 91
 92ping() ->
 93    %% Send a PING command every 15s
 94    erlang:send_after(15000, self(), ping).
 95
 96send_events(_, _, []) ->
 97    ok;
 98send_events(YawsPid, Domain, [#uce_event{datetime=Datetime} = Event|Events]) ->
 99    yaws_api:stream_chunk_deliver(YawsPid, "data: "),
100    yaws_api:stream_chunk_deliver(YawsPid, mochijson:encode(json_helpers:to_json(Domain, Event))),
101    yaws_api:stream_chunk_deliver(YawsPid, "\nid: "),
102    yaws_api:stream_chunk_deliver(YawsPid, integer_to_list(Datetime)),
103    yaws_api:stream_chunk_deliver(YawsPid, "\n\n"),
104    send_events(YawsPid, Domain, Events).