如何使用 WebSockex 公开我自己的 Elixir websocket

How do I expose my own Elixir websocket using WebSockex

我看到了 Elixir 的 WebSockex 库的基本示例 here but it doesn't really explain how I can expose my own websocket to the internet. 有解释如何在外部与现有 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 都帮不上忙,我有什么选择?

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()}}
    ]
  ]
}

老实说,我只使用原始 plug 完成了此操作,因此您可能需要将端点转换为 Plug 而不是 Phoenix.Endpoint。然后,您需要实现 YourApp.WebsocketHandler 以符合 cowboy 的 API 并执行 websocket 升级(并处理 sending/receiving 消息),如 in cowboy docs. You can also see this gist 所述一个更充实的例子。

WebSockex实现了很多回调,包括但不限于WebSockex.handle_connect/2. It holds WebSockex.Conn在一个状态下传递给所有的回调。

WebSockex.Conn 是一个普通的旧 struct, having socket 字段。

所以从任何回调(我会从 WebSockex.handle_connect/2 开始)你可以与需要它的进程共享这个套接字,然后从那里使用它。


此外,您可以借用一些内部构件并检查连接方式 is being created

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


OSS 的强大之处在于单击鼠标即可获得所有答案,而不是问题。