Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 89 lines (77 sloc) 2.549 kb
c4fd143 @vinoski add support for W3C Server-Sent Events
vinoski authored
1 %%%----------------------------------------------------------------------
2 %%% File : server_sent_events.erl
3 %%% Author : Steve Vinoski <vinoski@ieee.org>
4 %%% Purpose : Server-Sent Events example
5 %%% Created : 1 June 2012 by Steve Vinoski <vinoski@ieee.org>
6 %%%----------------------------------------------------------------------
7 -module(server_sent_events).
8 -behaviour(gen_server).
9
10 -include("yaws_api.hrl").
11
12 %% API
13 -export([out/1]).
14
15 %% gen_server callbacks
16 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
17 terminate/2, code_change/3]).
18
19 -record(state, {
20 sock,
21 yaws_pid,
22 timer
23 }).
24
25 out(A) ->
26 case (A#arg.req)#http_request.method of
27 'GET' ->
28 case yaws_api:get_header(A#arg.headers, accept) of
29 undefined ->
30 {status, 406};
31 Accept ->
32 case string:str(Accept, "text/event-stream") of
33 0 ->
34 {status, 406};
35 _ ->
36 {ok, Pid} = gen_server:start(?MODULE, [A], []),
37 yaws_sse:headers(Pid)
38 end
39 end;
40 _ ->
a721cfc @vinoski minor changes to server-sent events
vinoski authored
41 [{status, 405},
42 {header, {"Allow", "GET"}}]
c4fd143 @vinoski add support for W3C Server-Sent Events
vinoski authored
43 end.
44
45 init([Arg]) ->
46 process_flag(trap_exit, true),
47 {ok, #state{sock=Arg#arg.clisock}}.
48
49 handle_call(_Request, _From, State) ->
50 {reply, ok, State}.
51
52 handle_cast(_Msg, State) ->
53 {noreply, State}.
54
da6d73c @vinoski remove unnecessary inet:setopts from server-sent events example
vinoski authored
55 handle_info({ok, YawsPid}, State) ->
c4fd143 @vinoski add support for W3C Server-Sent Events
vinoski authored
56 {ok, Timer} = timer:send_interval(1000, self(), tick),
57 {noreply, State#state{yaws_pid=YawsPid, timer=Timer}};
58 handle_info({discard, _YawsPid}, State) ->
59 %% nothing to do
60 {stop, normal, State};
61 handle_info(tick, #state{sock=Socket}=State) ->
8862645 @vinoski use localtime not universaltime for server_sent_events example
vinoski authored
62 Time = erlang:localtime(),
c4fd143 @vinoski add support for W3C Server-Sent Events
vinoski authored
63 Data = yaws_sse:data(httpd_util:rfc1123_date(Time)),
2ad166a @vinoski server_sent_events: end gen_server process if send fails
vinoski authored
64 case yaws_sse:send_events(Socket, Data) of
65 ok ->
66 {noreply, State};
67 {error, closed} ->
68 {stop, normal, State};
69 {error, Reason} ->
70 {stop, Reason, State}
71 end;
c4fd143 @vinoski add support for W3C Server-Sent Events
vinoski authored
72 handle_info({tcp_closed, _}, State) ->
73 {stop, normal, State#state{sock=closed}};
74 handle_info(_Info, State) ->
75 {noreply, State}.
76
77 terminate(_Reason, #state{sock=Socket, yaws_pid=YawsPid, timer=Timer}) ->
78 case Timer of
79 undefined ->
80 ok;
81 _ ->
82 timer:cancel(Timer)
83 end,
84 yaws_api:stream_process_end(Socket, YawsPid),
85 ok.
86
87 code_change(_OldVsn, State, _Extra) ->
88 {ok, State}.
Something went wrong with that request. Please try again.