Sending a channel message to all windows of a certain user

238 views
Skip to first unread message

yuri.l...@gmail.com

unread,
Sep 2, 2015, 5:58:25 AM9/2/15
to phoenix-talk

Hello everyone


 I have websockets authenticated with Phoenix.Token:


  def connect(%{"token" => token}, socket) do

    case Phoenix.Token.verify(socket, "user_id", token, max_age: @two_weeks) do

      {:ok, user_id} ->  {:ok, assign(socket, :user, user_id)}

      {:error, reason} -> :error

    end

  end


and my socket module exposes function `id`


  def id(socket),  do: "users_socket:#{user_id(socket)}"


  def user_id(socket), do: socket.assigns[:user]



which, as far as I understand, makes it possible to register all sockets in the PubSub server with a topic like "users_socket:42".


This allows me to run 


Foo.Endpoint.broadcast("users_socket:42", "disconnect", %{})


which sends a disconnect message to all sockets of the user with ID 42. It does work. 


But how do I send a channel message to all windows of that user? I need a way to send messages to browser windows on some server side event.


All my attempts such as the following


pubsub_server =  Foo.Endpoint.__pubsub_server__

Phoenix.PubSub.broadcast! pubsub_server, "users_socket:42", %Phoenix.Socket.Broadcast{

  topic: "mychannel:main",

  event: "msg",

  payload: %{body: "hello there"}

}



have failed. 


I am definitely missing something.


Best regards,

Yuri

Chris McCord

unread,
Sep 2, 2015, 7:49:31 AM9/2/15
to phoeni...@googlegroups.com
You would do this by broadcasting on a channel that the user has joined. The socket id is a special case only for terminating that socket connection. You could have a UserChannel that each client joins with their user id as the subtopic, then you broadcast to that. Make sense?


--
You received this message because you are subscribed to the Google Groups "phoenix-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to phoenix-talk...@googlegroups.com.
To post to this group, send email to phoeni...@googlegroups.com.
Visit this group at http://groups.google.com/group/phoenix-talk.
To view this discussion on the web visit https://groups.google.com/d/msgid/phoenix-talk/d81fb01a-85b6-4ff4-ada9-fc84f317a300%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Yuri Leikind

unread,
Sep 2, 2015, 8:03:44 AM9/2/15
to phoeni...@googlegroups.com
Yes, it does. Now I wonder why I didn't use channel subtopics in the first place, this is so simple :-/ !

Thank you!

Best regards,
Yuri

--
You received this message because you are subscribed to a topic in the Google Groups "phoenix-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/phoenix-talk/H9z_5fb7vr4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to phoenix-talk...@googlegroups.com.

To post to this group, send email to phoeni...@googlegroups.com.
Visit this group at http://groups.google.com/group/phoenix-talk.

For more options, visit https://groups.google.com/d/optout.



--
Best regards,
Yuri Leikind

Sent from my Nokia 3310

an.jos...@gmail.com

unread,
Dec 26, 2017, 5:45:48 AM12/26/17
to phoenix-talk
Hi Chris what do you think is the best way to set the user id from the client side in JS when trying to join "user:<user_id>" channel? I'm having difficulty accessing the user_id, I only have the window.userToken which is a long string. Should I set a window.userId = <%= assigns.current_user.id %> ? Currently I am using the signed Phoenix.Token as the channel id "user:<window.userToken>", then in my channel's join function I verify the token. Like so:
def join("user:" <> token, _params, socket) do
    case Phoenix.Token.verify(socket, "user socket", token, max_age: @max_age) do
    {:ok, ^socket.assigns.user_id} -> {:ok, socket}
    {:error, _reason} -> {:error, "permission denied"}
  end
end
Reply all
Reply to author
Forward
0 new messages