Cannot connect to the socket (websockets newbie)

I have a Phoenix server (named Backend).
I created a channel called ShoppingListChannel with:

mix ShoppingListChannel

As instructed I added the channel to lib/backend_web/channels/user_socket.ex:

defmodule BackendWeb.UserSocket do
  use Phoenix.Socket

  ## Channels
  # channel "room:*", BackendWeb.RoomChannel
  channel "shopping_list_channel:lobby", BackendWeb.ShoppingListChannelChannel
  # Socket params are passed from the client and can
  # be used to verify and authenticate a user. After
  # verification, you can put default assigns into
  # the socket that will be set for all channels, ie
  #     {:ok, assign(socket, :user_id, verified_user_id)}
  # To deny connection, return `:error`.
  # See `Phoenix.Token` documentation for examples in
  # performing token verification on connect.
  def connect(_params, socket, _connect_info) do
    {:ok, socket}

  # Socket id's are topics that allow you to identify all sockets for a given user:
  #     def id(socket), do: "user_socket:#{socket.assigns.user_id}"
  # Would allow you to broadcast a "disconnect" event and terminate
  # all active sockets and channels for a given user:
  #     BackendWeb.Endpoint.broadcast("user_socket:#{}", "disconnect", %{})
  # Returning `nil` makes this socket anonymous.
  def id(_socket), do: nil

I changed the join function because at this point I do not care about the payload:

defmodule BackendWeb.ShoppingListChannelChannel do
  use BackendWeb, :channel

  def join("shopping_list_channel:lobby", _payload, socket) do
    {:ok, socket}
    #if authorized?(payload) do
    #  {:ok, socket}
    #  {:error, %{reason: "unauthorized"}}

  # Channels can be used in a request/response fashion
  # by sending replies to requests from the client
  def handle_in("ping", payload, socket) do
    {:reply, {:ok, payload}, socket}

  # It is also common to receive messages from the client and
  # broadcast to everyone in the current topic (shopping_list_channel:lobby).
  def handle_in("shout", payload, socket) do
    broadcast socket, "shout", payload
    {:noreply, socket}

  # Add authorization logic here as required.
  defp authorized?(_payload) do

My problem is I tried to connect to the socket and then a channel with JS from a separate front-end, but it does not work:

var ws = new WebSocket("ws://localhost:4000/socket")

Any advices?


You probably need to use Socket from phoenix.js (bundled with :phoenix) client instead of plain WebSocket browser api:

let socket = new Socket("/socket")

If, however, you want to use WebSocket, you’d use it like this (note the path and query string)

let ws = new WebSocket("ws://localhost:4000/socket/websocket?vsn=2.0")

and also check out the source code for phoenix.js to see what else it does on top of websockets to make channels work (Pushes, channel tracking, etc).


A small correction, because the WebSocket code did not work:

let ws = new WebSocket("ws://localhost:4000/socket/websocket?vsn=2.0.0")

You need to use the phoenix.js client library unless you want to reproduce all the things it does.