【问题标题】:Phoenix: Trying to connect to Channel but getting a not Route found for GET /websocket errorPhoenix:尝试连接到 Channel 但未找到 GET /websocket 错误的路由
【发布时间】:2016-11-14 01:20:12
【问题描述】:

我正在尝试使用 Channels (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

在前端,使用phoenix js客户端:

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

有人知道怎么回事吗?

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    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) 让我有些困惑,但现在已经清除了。

    【讨论】:

    • 感谢这个问题/答案,它也帮助我解决了 url 问题。对于那些偶然发现这里的人,客户端应该尝试连接到 ws://localhost:4000/socket/websocket。在这种情况下,Phoenix 会建立一个 websocket 连接。
    猜你喜欢
    • 2019-03-25
    • 2021-01-29
    • 2016-06-24
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 2015-08-15
    • 2018-12-25
    • 1970-01-01
    相关资源
    最近更新 更多