I'm trying to tie together the Phoenix Channel, Token, and Presence modules to add chat functionality to my Phoenix 1.3 application. I haven't been able to get all 3 modules working together. The last error was connection to websocket closed before handshake
. Now, I'm not getting any errors but it's also not connecting to the socket.
I believe the issue is the "connect" function in the player_socket.ex. ( I have a player resource ). Here is the function:
def connect(%{"token" => token}, socket) do
case Phoenix.Token.verify(socket, "player auth", token, max_age: @max_age) do
{:ok, player_id} ->
player = Repo.get!(Player, player_id)
{:ok, assign(socket, :current_player, player)}
{:error, _reason} ->
:error
end
end
I'm signing the token in a meta tag in app.html.eex. <%= tag :meta, name: "channel_token", content: Phoenix.Token.sign(@conn, "player auth", :player_id) %>
Then in the lobby_channel.ex I'm trying to join the channel:
def join("lobby:lobby", _params, socket) do
send(self(), :after_join)
{:ok, assign(socket, :player_id, :current_player)}
end
def handle_info(:after_join, socket) do
push socket, "presence_state", Presence.list(socket)
{:ok, _} = Presence.track(socket, socket.assigns.current_player, %{
online_at: inspect(System.system_time(:seconds))
})
{:noreply, socket}
end
I read the docs but can't seem to figure out why I'm unable to connect to the websocket with the "current_player" so that I can use Presence to display who is online and the player's names to associate with their chat messages. Any insight is greatly appreciated! I have the repo here: https://github.com/EssenceOfChaos/gofish
UPDATE
I am using a "current_player" plug to store the player struct in the conn as "current_player.
%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...},
assigns: %{current_player: %Gofish.Accounts.Player{__meta__: #Ecto.Schema.Metadata<:loaded, "players">,
email: "[email protected]", id: 6,
Here is my updated lobby_channel.ex:
def join("lobby:lobby", _params, socket) do
send(self(), :after_join)
{:ok, socket}
end
def handle_info(:after_join, socket) do
push socket, "presence_state", Presence.list(socket)
{:ok, _} = Presence.track(socket, socket.assigns.current_player.id, %{
username: socket.assigns.current_player.username,
online_at: inspect(System.system_time(:seconds))
})
{:noreply, socket}
end