Current section
Files
Jump to
Current section
Files
src/shimmer@ws@event_loop.erl
-module(shimmer@ws@event_loop).
-compile(no_auto_import).
-export([websocket_actor/1]).
-export_type([message/0, identify_info/0, state/0, spec/0]).
-type message() :: heartbeat_now | {frame, binary()}.
-type identify_info() :: {identify_info, binary(), integer()}.
-type state() :: {state,
integer(),
integer(),
nerf@websocket:connection(),
identify_info()}.
-type spec() :: {spec, fun(() -> state()), fun((message(), state()) -> state())}.
-spec heartbeat(state()) -> state().
heartbeat(State) ->
erlang:send_after(
erlang:element(2, State),
gleam@otp@process:self(),
heartbeat_now
),
case gleam@int:compare(erlang:element(3, State), -1) of
gt ->
shimmer@ws@ws_utils:gateway_heartbeat(
erlang:element(3, State),
erlang:element(4, State)
);
_@1 ->
shimmer@ws@ws_utils:gateway_heartbeat_null(erlang:element(4, State))
end,
State.
-spec handle_hello(
shimmer@types@packet:packet(),
shimmer@types@hello_event:hello_event(),
state()
) -> state().
handle_hello(Packet, Data, State) ->
erlang:send_after(0, gleam@otp@process:self(), heartbeat_now),
shimmer@ws@ws_utils:gateway_identify(
erlang:element(2, erlang:element(5, State)),
erlang:element(3, erlang:element(5, State)),
erlang:element(4, State)
),
erlang:setelement(2, State, erlang:element(2, Data)).
-spec handle_frame(binary(), state()) -> state().
handle_frame(Frame, State) ->
case shimmer@ws@ws_utils:ws_frame_to_packet(Frame) of
{ok, Packet} ->
case erlang:element(2, Packet) of
0 ->
case erlang:element(4, Packet) of
{some, Event} ->
case Event of
E ->
gleam@io:println(
begin
_pipe = <<"Unknown Event: "/utf8>>,
gleam@string:append(_pipe, E)
end
)
end,
State;
none ->
State
end;
10 ->
case erlang:element(5, Packet) of
{some, Packet_data} ->
case shimmer@types@hello_event:from_dynamic(
Packet_data
) of
{ok, Hello_data} ->
handle_hello(Packet, Hello_data, State);
{error, _@1} ->
State
end;
none ->
State
end;
11 ->
State;
_@2 ->
gleam@io:println(
begin
_pipe@1 = <<"Unknown Packet ["/utf8>>,
_pipe@2 = gleam@string:append(
_pipe@1,
gleam@int:to_string(erlang:element(2, Packet))
),
_pipe@3 = gleam@string:append(
_pipe@2,
<<"] "/utf8>>
),
gleam@string:append(_pipe@3, Frame)
end
),
State
end;
{error, _@3} ->
gleam@io:println(
begin
_pipe@4 = <<"Invalid Packet "/utf8>>,
gleam@string:append(_pipe@4, Frame)
end
),
State
end.
-spec handle_message(message(), state()) -> state().
handle_message(Msg, State) ->
case Msg of
heartbeat_now ->
heartbeat(State);
{frame, Frame} ->
handle_frame(Frame, State)
end.
-spec websocket_actor(identify_info()) -> {ok, gleam@otp@process:pid_()} |
{error, gleam@dynamic:dynamic()}.
websocket_actor(Identify_info) ->
shimmer_event_loop:start_link(
{spec,
fun() ->
{ok, Conn@1} = case shimmer@ws@ws_utils:open_gateway() of
{ok, Conn} -> {ok, Conn};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"shimmer/ws/event_loop"/utf8>>,
function => <<"websocket_actor"/utf8>>,
line => 120})
end,
{state, 41250, -1, Conn@1, Identify_info}
end,
fun handle_message/2}
).