62 lines
1.8 KiB
Erlang
62 lines
1.8 KiB
Erlang
-module(wsio_handler).
|
|
|
|
-export([init/2]).
|
|
-export([websocket_handle/2]).
|
|
-export([websocket_init/1]).
|
|
-export([websocket_info/2]).
|
|
|
|
-define(TTL_PING, 10000).
|
|
|
|
init(R, _) ->
|
|
{cowboy_websocket, R, #{}}.
|
|
|
|
websocket_init(S) ->
|
|
Ref = st:lookup(wsbus),
|
|
erlang:send_after(?TTL_PING, self(), ping),
|
|
{ok, S#{wsbus => nil, ref_wsbus => Ref}}.
|
|
|
|
websocket_handle({text, <<Data/binary>>}, S) ->
|
|
case jsx:is_json(Data) of
|
|
true ->
|
|
websocket_handle({json, jsx:decode(Data)}, S);
|
|
false ->
|
|
{ok, S}
|
|
end;
|
|
websocket_handle({json, #{<<"ref">> := Ref}}, #{wsbus := nil} = S) ->
|
|
{[{text, jsx:encode(#{<<"ref">> => Ref, <<"wsio-code">> => 0})}], S};
|
|
websocket_handle({json, Data}, #{wsbus := BUS} = S) ->
|
|
gen_server:cast(BUS, {call, Data, self()}),
|
|
{ok, S};
|
|
websocket_handle(_, State) ->
|
|
{ok, State}.
|
|
|
|
websocket_info(close, S) ->
|
|
{[close], S};
|
|
websocket_info(ping, S) ->
|
|
erlang:send_after(?TTL_PING, self(), ping),
|
|
{[ping], S};
|
|
websocket_info({send, #{} = Map}, S) ->
|
|
{[{text, jsx:encode(Map)}], S};
|
|
websocket_info({send, <<Bin/binary>>}, S) ->
|
|
{[{text, Bin}], S};
|
|
websocket_info({send, List}, S) when is_list(List) ->
|
|
{List, S};
|
|
websocket_info({'DOWN', _, process, PID, _}, #{wsbus := PID} = S) ->
|
|
{ok, S#{wsbus => nil, ref_wsbus => st:lookup(wsbus)}};
|
|
websocket_info({_, {send, _} = Msg}, S) ->
|
|
websocket_info(Msg, S);
|
|
websocket_info({_, {Ref, {error, notfound}}}, #{ref_wsbus := Ref} = S) ->
|
|
{ok, S#{ref_wsbus => st:lookup(wsbus)}};
|
|
websocket_info({_, {Ref, {ok, Service}}}, #{wsbus := nil, ref_wsbus := Ref} = S) ->
|
|
try gen_server:call(Service, {new, self()}) of
|
|
{ok, PID} ->
|
|
erlang:monitor(process, PID),
|
|
{ok, maps:remove(ref_wsbus, S#{wsbus => PID})};
|
|
{error, ignored} ->
|
|
{ok, S#{ref_wsbus => st:lookup(wsbus)}}
|
|
catch
|
|
_:_ ->
|
|
{ok, S#{ref_wsbus => st:lookup(wsbus)}}
|
|
end;
|
|
websocket_info(_, S) ->
|
|
{ok, S}.
|