Phoenix:尝试连接到Channel,但未找到GET/websocket错误的路由 [英] Phoenix: Trying to connect to Channel but getting a not Route found for GET /websocket error

查看:179
本文介绍了Phoenix:尝试连接到Channel,但未找到GET/websocket错误的路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Channels(Websockets)将Angular 2前端连接到Phoenix应用程序.它们是完全分开的,并且可以在本地主机上的不同端口上运行(4000上的phoenix,5555上的angular 2).奇怪的是,后端出现了(Phoenix.Router.NoRouteError) no route found for GET /websocket (MyApp.Router)错误.前端出现代码1006错误:

I'm trying to hook up an Angular 2 frontend to a Phoenix app using Channels (Websockets). They are completely seperate and run on different ports on localhost (phoenix on 4000, angular 2 on 5555). Strangely I'm getting a (Phoenix.Router.NoRouteError) no route found for GET /websocket (MyApp.Router) error on the backend. And a code 1006 error on the frontend:

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客户端:

On the frontend, using the phoenix js client:

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

有人知道发生了什么事吗?

Does anyone know what's going on?

推荐答案

此问题得到了何塞·瓦利姆(JoséValim)的回答,它为我指明了正确的方向.

This question had an answer by José Valim that pointed me in the right direction.

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

the suffix of the path should be whatever the transport layer is. In this case, it needed /websocket at the end in the implementation.

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

So in my endpoint I changed the route from /websocket to /socket to prevent confusion:

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

  socket "/socket", TropeApi.PostSocket

  # ...

end

,然后更改js实现以反映这一点.我还向选项中添加了传输参数(只是要提一下,这与它有任何关系,我认为这是不对的.)

And then changed the js implementation to reflect that. I also added the transport parameter to the options (just to mention in case this has anything to do with it, which I don't think).

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)使我有些困惑,但现在已清除.

The connection now goes to ws://localhost:4000/socket/websocket. The last part (websocket) let to some confusion for me but was cleared up now.

这篇关于Phoenix:尝试连接到Channel,但未找到GET/websocket错误的路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆