Phoenix adding the string 'websocket' to the websocket connection url

i’m trying to connect to the phoenix backend using the js client lib. I defined the route for the websocket on the endpoint.ex

defmodule TestespayWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :testespay
  @session_options [
    store: :cookie,
    key: "_testespay_key",
    signing_salt: "sLyVi0bu",
    same_site: "Lax"
  ]

  socket "/ws/wallet", TestespayWeb.WalletSocket,
  websocket: true,
  longpoll: false

  socket "/live", Phoenix.LiveView.Socket,
    websocket: [connect_info: [session: @session_options]],
    longpoll: [connect_info: [session: @session_options]]

client code

import {Socket} from "phoenix"

// And connect to the path in "lib/testespay_web/endpoint.ex". We pass the
// token for authentication. Read below how it should be used.
let socket = new Socket("/ws/walet", {params: {token: "pubkey"}})

export function connect_websocket(param) {
  let socket = new Socket("ws://localhost:4000/ws/walet", {params: {pubkey: param}})
  socket.connect()
  return socket
}

socket

defmodule TestespayWeb.WalletSocket do
  use Phoenix.Socket

  # Define os canais
  channel "wallet:balances", TestespayWeb.WalletChannel

  @impl true
  def connect(%{"pubkey" => pubkey}, socket, _connect_info) do
    Logger.debug("WalletSocket connect")
    {:ok, assign(socket, :wallet_pubkey, pubkey)}

  end

  def connect(_params, _socket, _connect_info) do
    :error
  end

  @impl true
 def id(socket), do: "wallet_socket:#{socket.assigns.wallet_pubkey}"

end

when I try to connect it goes to a endpoint with ‘websocket’ incorporated

GET /ws/walet/websocket
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /ws/walet/websocket (TestespayWeb.Router)
    (testespay 0.1.0) deps/phoenix/lib/phoenix/router.ex:541: TestespayWeb.Router.call/2
    (testespay 0.1.0) lib/testespay_web/endpoint.ex:1: TestespayWeb.Endpoint.plug_builder_call/2
    (testespay 0.1.0) deps/plug/lib/plug/debugger.ex:136: TestespayWeb.Endpoint."call (overridable 3)"/2
socket.js:348 WebSocket connection to 'ws://localhost:4000/ws/walet/websocket?pubkey=xiiiisieioi&vsn=2.0.0' failed:

my router code

defmodule TestespayWeb.Router do
  use TestespayWeb, :router


  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    # plug :put_root_layout, html: {TestespayWeb.Layouts, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end


  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", TestespayWeb do
    pipe_through :browser
    get "/home", HomeController, :show
  end


  scope "/api", TestespayWeb do
    pipe_through :api

    post "/create_contract", ContractController, :create
    get "/identify", IdentifyController, :find
  end

  if Application.compile_env(:testespay, :dev_routes) do
    import Phoenix.LiveDashboard.Router

    scope "/dev" do
      pipe_through :browser

      live_dashboard "/dashboard", metrics: TestespayWeb.Telemetry
      forward "/mailbox", Plug.Swoosh.MailboxPreview
    end
  end
end

what configuration extra I need to do?

I tried to modify the client url with a extra websockt string to see if it would work

export function connect_websocket(param) {
  let socket = new Socket("ws://localhost:4000/ws/walet/websocket", {params: {pubkey: param}})
  socket.connect()
  return socket
}

now the url has 2 websockets strings

conn
: 
WebSocket {timeout: 20000, url: 'ws://localhost:4000/ws/walet/websocket/websocket?pubkey=xiiiisieioi&vsn=2.0.0'

That’s normal because long polling uses a different path than websocket. You don’t specify them on the backend because the socket automatically supports both.

/websocket is added here: phoenix/assets/js/phoenix/socket.js at 853f824167b3595053ed23f73f06ca59e5ac95b6 · phoenixframework/phoenix · GitHub

/longpoll would be added here: phoenix/assets/js/phoenix/longpoll.js at 853f824167b3595053ed23f73f06ca59e5ac95b6 · phoenixframework/phoenix · GitHub

You seem to have a typo walet on the frontend vs wallet on the backend, which may be the cause of your issue.

1 Like