查看原始碼 為頻道用戶端撰寫程式碼
適用於 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"}]