如何使用 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 的强大之处在于单击鼠标即可获得所有答案,而不是问题。
我看到了 Elixir 的 WebSockex 库的基本示例 here but it doesn't really explain how I can expose my own websocket to the internet.
我显然知道我的 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 的强大之处在于单击鼠标即可获得所有答案,而不是问题。