I have these two channels: UserChannel and PrivateChannel. UserChannel is the user’s own lobby and an example of joining that channel is user:3 where 3 is the user’s id. An example of joining private channel is private:3:23 where 3 is the id of the first user and 23 is the id of the second user.
The series of events that a user would take is as follows: In the client side when the user login, I create the socket and send in the user’s id as the socket’s param and try to connect to the UserChannel; this occurs successfully. When the user wants to initiate a private chat, they search by name and a series of profiles appear. Once they click on it, a function called startPrivateChat fires and calls the connectToPrivateChat defined in my chat.js. What happens is that I get a join crash because my join/3 function in App.PrivateChannel is undefined.
Now in the phoenix documentation and from multiple other sources, they say that all I need is one socket and I can use that socket to multiplex to different channels. So what I did is create a chat.js service that references things like the socket, the two channels(this.user_channel and this.private_channel) and another methods like connectToSocket, connectToUserChannel, connectToPrivateChannel etc. So why is this happening and what exactly am I doing wrong?
P.S - I’m using Phoenix 1.2 and Elixir 1.6.5
user_socket.ex
defmodule AppChat.UserSocket do
use Phoenix.Socket
channel "user:*", AppChat.UserChannel
channel "private:*", AppChat.PrivateChannel
transport :websocket, Phoenix.Transports.WebSocket
def connect(%{ "user_id" => id }, socket) do
current_user = AppChat.Repo.get(AppChat.User, String.to_integer(id))
{:ok, assign(socket, :current_user, current_user)}
end
def id(socket), do: "user_socket:#{socket.assigns.current_user.id}"
end
user_channel.ex
defmodule AppChat.UserChannel do
use AppChat.Web, :channel
require Logger
def join("user:" <> user_id, _payload, socket) do
if socket.assigns.current_user.id == String.to_integer(user_id) do
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
end
private_channel.ex
defmodule AppChat.PrivateChannel do
use AppChat.Web, :channel
require Logger
def join("private:" <> users_string, _payload, socket) do
if users_string |> String.split(":") |> Enum.member?(socket.assigns.current_user.id) do
{:ok, %{}, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
end