Chris McCord 展示了单个 Phoenix 服务器如何支持一百万个连接。这意味着一百万人在仅由单个物理服务器提供支持的聊天应用程序中发送和接收消息。您可能更熟悉典型的单向服务器请求。客户端向服务器请求信息,服务器响应。 Websockets 允许客户端和服务器之间的直接双向通信。因此,对于大多数实时应用程序,WebSockets 更可取。在任何时候,客户端或服务器都可以向对方发送消息。 Websockets 是 Phoenix 中默认的实时通信方式。长轮询是另一种不太流行的实时功能通信协议,通常在客户端互联网连接不佳时使用。长轮询是请求和响应的连续循环,而不是开放的双向通信。客户端建立连接。然后连接保持打开状态,直到服务器超时或响应。然后客户端重新建立连接,循环继续。这允许服务器控制何时更新客户端并使互联网连接不佳的客户端受益。
“如果出现问题,例如网络连接不良,客户端可以从 WebSocket 更改为长轮询。” - Pragmatic Programmer Channels 是 Phoenix 的一个令人兴奋的部分,它支持与数百万个连接的客户端以及它们之间的软实时通信。诸如“进球得分”或“地震即将来临”之类的突发新闻,凤凰频道允许在许多客户之间进行实时功能。这就是实践中的样子。 Phoenix 提供了您开始使用实时功能所需的一切。需要了解的重要部分是端点、套接字、主题和通道。端点是对您的 Web 应用程序的所有请求开始的边界。它也是您的应用程序提供给底层 Web 服务器的接口。提供用于启动和停止端点的包装器作为监督树的一部分
在您的 Phoenix 应用程序中的 endpoint.ex 文件中,您会注意到 Endpoint 默认设置了用户套接字。它还设置了一个 LiveView 套接字,但我们将重点关注用户套接字。默认情况下,Phoenix 使用 WebSockets 而不是长轮询,但它同时支持两者。注意 socket 方法中的 websockets: true 和 longpolling: false 。套接字必须定义两个回调,connect 和 id。这些回调用于验证和识别套接字连接。套接字管理您的 Phoenix 应用程序中的不同通道。您可以使用 Phoenix.Socket 模块提供的内置通道方法连接特定上下文下的通道。 channel 方法接受两个值,消息的上下文和在该上下文下处理消息的 Channel 模块。例如,这里是如何将聊天上下文下的所有消息连接到 ChatChannel。星号 * 是通配符。这意味着 ChatChannel 处理聊天主题下的所有事件。默认情况下,生成的频道包含一个 join 方法,用于处理将客户端连接到频道。这种加入方法使用了授权?方法作为您将来可能想要实现的任何授权逻辑的占位符。默认情况下,所有加入请求都被授权。通道使用 handle_in 方法来处理从客户端接收消息。 handle_in 方法的第一个参数是要进行模式匹配的事件名称字符串。客户端发送相同的事件名称字符串,以便通道知道哪个 handle_in 方法应该处理传入的消息。
Phoenix 提供了一个 socket.js 文件来处理从客户端到服务器的连接。在那里你会发现一些样板代码来处理连接到一个频道。更改该代码以匹配您的主题和副主题。这应该与您用于频道加入方法的字符串相匹配。使用 mix phx.server 启动您的 phoenix 项目并打开您的浏览器控制台(通常为 f12),您将看到您已成功加入。如果将这两种方法都添加到 socket.js 文件中,则效果如下所示。您可以使用凤凰频道中的 handle_out 方法拦截消息。您可以覆盖值、执行身份验证或添加其他信息。每当 handle_in 方法使用相同的事件字符串调用广播方法时,就会触发 handle_out 方法。在这种情况下,“喊”。您还必须在 Phoenix 频道内的拦截调用中包含事件名称。
要将消息推送到 handle_out 方法内部的客户端,请使用 push 方法。当您在浏览器控制台中加载应用程序时,您将看到带有额外信息的负载。现在,您了解了使用 Phoenix Channels 处理接收、发送和拦截消息所需的一切。如果您想了解更多关于凤凰频道可以做什么,那么凤凰文档是一个很好的起点!