查看原始碼 為頻道用戶端撰寫程式碼

適用於 Phoenix 頻道的用戶端函式庫在 多種語言中 已經存在,但如果您想自行撰寫,本指南將助您入門。它對於以 WebSocket 用戶端進行手動測試來說,也可能是一個有用的指南。

概述

因為 WebSocket 是雙向的,訊息隨時可能雙向傳遞。基於此原因,用戶端通常使用回呼函數來在訊息傳送進來時處理它們。

用戶端必須加入至少一個主題才能開始發送和接收訊息,並可以使用相同的連線加入任意數量的主題。

連線

如要建立與 Phoenix 頻道的 WebSocket 連線,請先記下應用程式 Endpoint 模組中 socket 的宣告。例如,如果您看到:socket "/mobile", MyAppWeb.MobileSocket,則初始 HTTP 要求的路徑為

[host]:[port]/mobile/websocket?vsn=2.0.0

傳遞 &vsn=2.0.0 表示 Phoenix.Socket.V2.JSONSerializer,它內建於 Phoenix 之中,並以清單形式接收和傳回訊息。

您還需要包含 升級 HTTP 要求為 WebSocket 連線的標準標題欄位,或使用一個 HTTP 函式庫來為您處理這件事;在 Elixir 中,mint_web_socket 是一個範例。

應用程式 Socket 模組中的特定 connect/3 函數可能需要或要求其他參數或標頭欄位(在上述範例中,為 MyAppWeb.MobileSocket.connect/3)。

訊息格式

訊息格式由為應用程式設定的序列化器決定。對於這些範例,假設的是 Phoenix.Socket.V2.JSONSerializer

用戶端傳送給 Phoenix 頻道的訊息的通常格式如下

[join_reference, message_reference, topic_name, event_name, payload]
  • 客戶端也必須選擇 join_reference,而且必須是唯一值。它只會在 "phx_join" 事件中傳送;對於其他訊息,它可以是 null。它用於從伺服器發送 push 訊息的訊息參考,即沒有針對特定客戶端訊息回覆的訊息。例如,「一位新使用者加入聊天室」。
  • 客戶端必須選擇 message_reference,而且必須是唯一值。伺服器會在回覆中附上它,讓客戶端得知回覆是針對哪則訊息。
  • topic_name 必須是 socket 端點已知的 topic,而且客戶端必須先加入該 topic,才能在上面傳送任何訊息。
  • event_name 必須符合伺服器通道模組中 handle_in 函式的第一個引數。
  • payload 應該為對應,並作為第二個引數傳遞給 handle_in 函式。

每一個 Phoenix 應用程式都了解三個事件。

首先,phx_join 用於加入頻道。例如,要加入 miami:weather 頻道

["0", "0", "miami:weather", "phx_join", {"some": "param"}]

其次,phx_leave 用於離開頻道。例如,要離開 miami:weather 頻道

[null, "1", "miami:weather", "phx_leave", {}]

第三,heartbeat 用於維護 WebSocket 連線。例如

[null, "2", "phoenix", "heartbeat", {}]

僅在不會傳送其他訊息時才需要 heartbeat 訊息,並且可以防止 Phoenix 關閉連線;確切的 :timeout 是在應用程式的 Endpoint 模組中設定。

其他允許的訊息取決於 Phoenix 應用程式。

例如,如果處理 miami:weather 的頻道可以處理 report_emergency 事件

def handle_in("report_emergency", payload, socket) do
  MyApp.Emergencies.report(payload) # or whatever
  {:reply, :ok, socket}
end

...客戶端可以發送

[null, "3", "miami:weather", "report_emergency", {"category": "sharknado"}]