forked from mmzeeman/elli_websocket
-
Notifications
You must be signed in to change notification settings - Fork 8
/
elli_example_websocket.erl
116 lines (90 loc) · 3.3 KB
/
elli_example_websocket.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
-module(elli_example_websocket).
-author("Maas-Maarten Zeeman <[email protected]>").
-export([init/2, handle/2, handle_event/3]).
%% Websocket callbacks.
-export([
websocket_init/2,
websocket_info/3,
websocket_handle/3,
websocket_handle_event/3
]).
-include_lib("elli/include/elli.hrl").
%% Serves as elli and websocket handler in one module.
-behaviour(elli_handler).
-behaviour(elli_websocket_handler).
%%
%% Elli Handler Callbacks
%%
%% It would be nice if it was possbile to somehow pass the fact
%% that this request is upgraded.
%%
init(Req, Args) ->
_Method = case elli_request:get_header(<<"Upgrade">>, Req) of
<<"websocket">> ->
init_ws(elli_request:path(Req), Req, Args);
_ ->
ignore
end.
handle(Req, Args) ->
Method = case elli_request:get_header(<<"Upgrade">>, Req) of
<<"websocket">> ->
websocket;
_ ->
elli_request:method(Req)
end,
handle(Method, elli_request:path(Req), Req, Args).
%%
%% Elli handler callbacks
%%
init_ws([<<"my">>, <<"websocket">>], _Req, _Args) ->
{ok, handover};
init_ws(_, _, _) ->
ignore.
handle('websocket', [<<"my">>, <<"websocket">>], Req, Args) ->
elli_websocket:upgrade(Req, Args),
%% websocket is closed:
%% See RFC-6455 (https://tools.ietf.org/html/rfc6455) for a list of
%% valid WS status codes than can be used on a close frame.
%% Note that the second element is the reason and is abitrary but should be meaningful
%% in regards to your server and sub-protocol.
{<<"1000">>, <<"Closed">>};
handle('GET', [<<"my">>, <<"websocket">>], _Req, _Args) ->
{200, [], <<"Use an upgrade request">>};
handle(_, _, _, _) ->
ignore.
handle_event(Name, EventArgs, ElliArgs) ->
io:fwrite(standard_error, "event: ~p ~p ~p~n", [Name, EventArgs, ElliArgs]),
ok.
%%
%% Elli websocket handler callbacks
%%
%% @doc
%%
websocket_init(Req, Opts) ->
io:fwrite(standard_error, "example_ws_init: ~p, ~p ~n", [Req, Opts]),
State = undefined,
{ok, [], State}.
websocket_info(_Req, Message, State) ->
io:fwrite(standard_error, "example_ws_info: ~p~n", [Message]),
{ok, State}.
websocket_handle(_Req, Message, State) ->
io:fwrite(standard_error, "example_ws_handle: ~p~n", [Message]),
%% default behaviour.
{ok, State}.
%% comment the line above ({ok, State}.)
%% and uncomment the line below for an echo server.
%% {reply, Message, State}.
%%
%% Elli Websocket Event Callbacks.
%%
%% websocket_open and websocket_close events are sent when the websocket
%% opens, and when it closes.
websocket_handle_event(websocket_open, [_, _Version, _Compress], _) -> ok;
websocket_handle_event(websocket_close, [_, _Reason], _) -> ok;
%% websocket_throw, websocket_error and websocket_exit events are sent if
%% the user callback code throws an exception, has an error or
%% exits. After triggering this event, a generated response is sent to
%% the user.
websocket_handle_event(websocket_throw, [_Request, _Exception, _Stacktrace], _) -> ok;
websocket_handle_event(websocket_error, [_Request, _Exception, _Stacktrace], _) -> ok;
websocket_handle_event(websocket_exit, [_Request, _Exception, _Stacktrace], _) -> ok.