5
votes

I am using phoenix framework, so:

I have the follow code at /web/static/js/socket.js

chatInput.on("keypress", event => {
  if (event.keyCode === 13) {
    channel.push("new_msg", {body: chatInput.val()}); //im want to pass @conn here
    chatInput.val("")
  }
});

and at /web/channels/room_channel:

use Phoenix.Channel
defmodule fooBar do
  def handle_in("new_msg", %{"body" => body}, socket) do #and get conn here
    broadcast! socket, "new_msg", %{body: body}
    {:noreply, socket}
  end
end

I need to get conn at room_channel. How can I pass it at socket.js?

1
Which conn do you want? and more importantly what are you trying to do with conn in a channel? (Asking because a Conn is only created for HTTP requests AFAIK.) - Dogbert
Im want to get user info from database, and im need conn because here is some info for query saved in session. So im want to: get conn -> find user in db -> fetch user info -> apply things like "username" to chat message - bartezr

1 Answers

5
votes

Here is the solution for you. In your router.ex.You put an user token like:

defp put_user_token(conn, _) do
  current_user = get_session(:current_user)
  user_id_token = Phoenix.Token.sign(conn, "user_id", current_user.id)
  conn |> assign(:user_id, user_id_token)
end

and then you can plug in your pipeline:

pipeline :browser do
 ...
 plug :put_user_token
end

and make sure you put your user token in your app.html.eex:

<script>window.userToken = "<%= assigns[:user_id] %>"</script>

Now you can check your socket in socket.js:

let socket = new Socket("/socket", {params: {token: window.userToken}})

and in your user_socket.ex.You can assign your token with socket:

def connect(%{"token" => user_id_token}, socket) do
    case Phoenix.Token.verify(socket, "user_id", user_id_token, max_age: 1209600) do
      {:ok, id} ->
        {:ok, assign(socket, :user_id, id)}
      {:error, reason} ->
        reason
    end
  end

Finally in your channel:

def handle_info(:after_join, socket) do 
    push socket, "user_joined", %{message: "User #{socket.assigns.user_id} has joined"
    {:noreply, socket}
end