1

我在这里看到了 Elixir 的 WebSockex 库的基本示例,但它并没有真正解释我如何将自己的 websocket 公开到互联网这个问题的答案解释了如何在外部与现有的 websocket 聊天,但我想公开我自己的 websocket。我实际上是在使用 websockex 作为 Phoenix 应用程序的一部分,所以 Phoenix 的一些可能在这里有所帮助?

我显然知道我的 phoenix 应用程序的 ip:port 组合,所以鉴于这些,我如何在该 ip:port 上公开一个 websockex websocket?换句话说,我应该传递什么作为 URL?在这个基本示例代码中:

defmodule WebSocketExample do
  use WebSockex

  def start_link(url, state) do
    WebSockex.start_link(url, __MODULE__, state)
  end

  def handle_frame({type, msg}, state) do
    IO.puts "Received Message - Type: #{inspect type} -- Message: #{inspect msg}"
    {:ok, state}
  end

  def handle_cast({:send, {type, msg} = frame}, state) do
    IO.puts "Sending #{type} frame with payload: #{msg}"
    {:reply, frame, state}
  end
end

请注意,我需要公开原始 websocket,而不是 Phoenix 频道,因为消费者不了解 Phoenix 频道。如果 Phoenix 可以公开原始 websocket,那么我也会认为这是一个解决方案。

如果 Phoenix 和 WebSockex 都无法提供帮助,我有什么选择?

4

2 回答 2

2

Websockex是一个客户端库,我认为它没有任何暴露 websocket 的代码。由于您已经在使用 phoenix,您可能可以使用phoenix channels做您需要的事情。

如果您正在使用cowboy(并且您可能正在使用,因为它是默认设置),那么您也可以使用它来公开原始 websocket。但是,它需要一些摆弄路由。您将需要YourAppWeb.Endpoint使用以下手动配置进行替换cowboy

{
  Plug.Cowboy,
  scheme: :http,
  plug: YourAppWeb.Endpoint,
  options: endpoint_options(),
  dispatch: [
    _: [
      # Dispatch paths beginning with /ws to a websocket handler
      {"/ws/[...]", YourApp.WebsocketHandler, []},
      # Dispatch other paths to the phoenix endpoint
      {:_, Plug.Cowboy.Handler, {YourAppWeb.Endpoint, endpoint_options()}}
    ]
  ]
}

老实说,我只使用 raw 完成此操作plug,因此您可能需要将端点转换为 aPlug而不是 a Phoenix.Endpoint。然后,您需要实现YourApp.WebsocketHandler符合cowboy的 API 并执行 websocket 升级(并处理发送/接收消息),如牛仔文档中所述。您还可以查看此要点以获得更充实的示例。

于 2021-03-01T13:15:13.493 回答
2

WebSockex实现许多回调,包括但不限于WebSockex.handle_connect/2. 它保持WebSockex.Conn一个状态并将其传递给所有回调。

WebSockex.Conn是一个普通的旧的好结构,有socket字段。

因此,从任何回调(我会从WebSockex.handle_connect/2)中,您可以与需要它的进程共享此套接字,然后从那里使用它。


此外,您可以借用一些内部结构并检查连接是如何创建的。

您将看到它使用WebSockex.Conn.new/2返回一个初始化连接,而该连接又持有一个套接字。在这种情况下,您将不得不手动监督持有套接字的进程。


OSS 的强大之处在于所有的答案都是一键点击,远离问题。

于 2021-03-01T14:06:18.703 回答