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

时间:2016-07-12 00:05:30

标签: 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

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

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

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

有谁知道发生了什么?

1 个答案:

答案 0 :(得分:12)

This question得到了JoséValim的回答,指出了我正确的方向。

  

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

因此,在我的终端中,我将路由从/websocket更改为/socket以防止混淆:

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

  socket "/socket", TropeApi.PostSocket

  # ...

end

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

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

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