defmodule PhaseDB.Server.Cowboy.WebsocketHandler do alias PhaseDB.Session alias PhaseDB.Server.Protocol require Logger @behaviour :cowboy_websocket_handler @moduledoc """ Implements the Cowboy websocket handler protocol. """ def init _transport, req, opts do init req, opts end def init req, opts do {:upgrade, :protocol, :cowboy_websocket, req, opts} end def upgrade req, env, _handler, handler_opts do :cowboy_websocket.upgrade req, env, __MODULE__, handler_opts end def websocket_init _transport, req, _ do case Session.create do {:ok, pid} -> send self, :send_init Process.monitor pid {:ok, req, %{session: pid}} e -> e end end def websocket_handle {:text, request}, req, %{session: pid}=state do {:reply, {:text, Protocol.handle(request, pid)}, req, state} end def websocket_info :send_init, req, state do {:reply, {:text, Protocol.init_message |> Poison.encode!}, req, state} end def websocket_info({:DOWN, _, :process, pid0, _}, req, %{session: pid1}=state) when pid0 == pid1 do send self, :shutdown {:reply, {:text, Protocol.error "Session disconnected"}, req, state} end def websocket_info({:DOWN, _, _, _, _}, req, state) do {:shutdown, req, state} end def websocket_info wat, req, state do IO.inspect wat {:shutdown, req, state} end def websocket_terminate _, _, %{session: pid} do Session.drop pid :ok end end