Phoenix:尝试连接到Channel但是找不到GET/websocket错误的Route

Ole*_*ann 7 elixir phoenix-framework

我正在尝试使用频道(Websockets)将Angular 2前端连接到Phoenix应用程序.它们是完全独立的并且在localhost上的不同端口上运行(凤凰4000,角度2,5555).奇怪的是我(Phoenix.Router.NoRouteError) no route found for GET /websocket (MyApp.Router)在后端收到错误.并且前端的代码1006错误:

WebSocket connection to 'ws://localhost:4000/websocket?vsn=1.0.0' failed: Error during WebSocket handshake: Unexpected response code: 404.

// endpoint.ex

defmodule MyApp.Endpoint do
  use Phoenix.Endpoint, otp_app: :my_app

  # socket "/socket", MyApp.UserSocket
  socket "/websocket", MyApp.PostSocket

  # Serve at "/" the static files from "priv/static" directory.
  #
  # You should set gzip to true if you are running phoenix.digest
  # when deploying your static files in production.
  plug Plug.Static,
    at: "/", from: :my_app, gzip: false,
    only: ~w(css fonts images js favicon.ico robots.txt)

  # Code reloading can be explicitly enabled under the
  # :code_reloader configuration of your endpoint.
  if code_reloading? do
    socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
    plug Phoenix.LiveReloader
    plug Phoenix.CodeReloader
  end

  plug Plug.RequestId
  plug Plug.Logger

  plug Plug.Parsers,
    parsers: [:urlencoded, :multipart, :json],
    pass: ["*/*"],
    json_decoder: Poison

  plug Plug.MethodOverride
  plug Plug.Head

  plug Plug.Session,
    store: :cookie,
    key: "_my_app_key",
    signing_salt: "qCSHk+9O"

    plug CORSPlug, [
      origin: "http://localhost:5555",
      headers: ["X-Auth-Token" | CORSPlug.defaults[:headers]]
    ]

  plug MyApp.Router
end
Run Code Online (Sandbox Code Playgroud)

PostSocket:

defmodule MyApp.PostSocket do
  use Phoenix.Socket

  ## Channels
  channel "post:*", MyApp.PostChannel

  ## Transports
  transport :websocket, Phoenix.Transports.WebSocket
  transport :longpoll, Phoenix.Transports.LongPoll


  def connect(_params, socket) do
    {:ok, socket}
  end

  def id(_socket), do: nil
end
Run Code Online (Sandbox Code Playgroud)

在前端,使用凤凰js客户端:

var socket = new Socket("ws://localhost:4000", {
  logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }),
  transport: WebSocket
});
socket.connect();
Run Code Online (Sandbox Code Playgroud)

有谁知道发生了什么?

Ole*_*ann 12

这个问题得到了JoséValim的回答,指出了我正确的方向.

路径的后缀应该是传输层的任何内容.在这种情况下,它在实现的最后需要/ websocket.

所以在我的终点,我改变从路线/websocket/socket防止混淆:

defmodule TropeApi.Endpoint do
  use Phoenix.Endpoint, otp_app: :trope_api

  socket "/socket", TropeApi.PostSocket

  # ...

end
Run Code Online (Sandbox Code Playgroud)

然后改变了js实现来反映这一点.我还将传输参数添加到选项中(仅提及如果它与它有任何关系,我不认为).

var socket = new Socket("ws://localhost:4000/socket", {
  logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }),
  transport: WebSocket
});
socket.connect();
Run Code Online (Sandbox Code Playgroud)

现在连接到了ws://localhost:4000/socket/websocket.最后一部分(websocket)让我感到困惑,但现在已经解决了.