websockets
import phxsocket
# endpoint.ex
socket "/socket", MyAppWeb.Socket, websocket: true, longpoll: false
socket = phxsocket.Client("wss://target.url/socket/websocket", {"name": "my name"})
Socket params go to Phoenix.Socket connect/3
# mysocket.ex
defmodule MyAppWeb.Socket do
use Phoenix.Socket
channel("channel:*", MyAppWeb.Channel)
def connect(%{"name" => name} = params, socket, _connect_info) do
{:ok, socket |> assign(name: name)}
end
def id(socket), do: nil
end
defmodule MyAppWeb.Channel do
use Phoenix.Channel
def join("channel:" <> room_name, %{"password" => password}, socket) do
if password == "1234" do
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
end
if socket.connect(): # blocking, raises exception on failure
channel = socket.channel("channel:my room", {"password": "1234"})
resp = channel.join() # also blocking, raises exception on failure
Alternatively
def connect_to_channel(socket):
channel = socket.channel("channel:my room", {"password": "1234"})
resp = channel.join()
socket.on_open = connect_to_channel
connection = socket.connect(blocking=False)
connection.wait() # blocking, raises exception on failure
socket.on_close = lambda socket: socket.connect()
def do_something(payload):
content = payload["content"]
channel.on("message", do_something)
MyAppWeb.Endpoint.broadcast("channel:my room", "message", %{"content": "hello"})
defmodule MyAppWeb.Channel do
...
def handle_in("message", %{"content" => content}, socket) do
IO.inspect("received from #{socket.assigns.name}: #{content}")
{:reply, {:ok, "hello"}, socket}
end
channel.push("message", {"content": "hello"})
This throws away the reply if the return value of handle_in is :reply
message = channel.push("message", {"content": "hello"}, reply=True)
payload = message.wait_for_response() # blocking
def response(payload):
print(payload["status"]) # ok
print(payload["response"]) # hello
channel.push("message", {"content": "hello"}, response)
channel.leave()
socket.close()