phoenix_gen_socket_client v2.1.1 Phoenix.Channels.GenSocketClient behaviour View Source
Communication with a Phoenix Channels server.
This module powers a process which can connect to a Phoenix Channels server and exchange messages with it. Currently, only websocket communication protocol is supported.
The module is implemented as a behaviour. To use it, you need to implement the
callback module. Then, you can invoke start_link/5
to start the socket process.
The communication with the server is then controlled from that process.
The connection is not automatically established during the creation. Instead,
the implementation can return {:connect, state}
to try to establish the
connection. As the result either handle_connected/2
or handle_disconnected/2
callbacks will be invoked.
To join a topic, join/3
function can be used. Depending on the result, either
handle_joined/4
or handle_join_error/4
will be invoked. A client can join
multiple topics on the same socket. It is also possible to leave a topic using
the leave/3
function.
Once a client has joined a topic, it can use push/4
to send messages to the
server. If the server directly replies to the message, it will be handled in
the handle_reply/5
callback.
If a server sends an independent message (i.e. the one which is not a direct
reply), the handle_message/5
callback will be invoked.
If the server closes the channel, the handle_channel_closed/4
will be invoked.
This will not close the socket connection, and the client can continue to
communicate on other channels, or attempt to rejoin the channel.
Sending messages over the socket
As mentioned, you can use join/3
, push/4
, and leave/3
to send messages to
the server. All of these functions require the transport
information as the
first argument. This information is available in most of the callback functions.
Functions will return {:ok, ref}
if the message was sent successfully,
or {:error, reason}
, where ref
is the Phoenix ref used to uniquely identify
a message on a channel.
Error responses are returned in following situations:
- The client is not connected
- Attempt to send a message on a non-joined channel
- Attempt to leave a non-joined channel
- Attempt to join the already joined channel
Keep in mind that there’s no guarantee that a message will arrive to the server. You need to implement your own communication protocol on top of Phoenix Channels to obtain such guarantees.
Process structure and lifecycle
The behaviour will internally start the websocket client in a separate child process. This means that the communication runs concurrently to any processing which takes place in the behaviour.
The socket process will crash only if the websocket process crashes, which can
be caused only by some bug in the websocket client library. If you want to
survive this situation, you can simply trap exits in the socket process, by
calling Process.flag(:trap_exit, true)
in the init/1
callback. In this case,
a crash of the websocket client process will be treated as a disconnect event.
The socket process never decides to stop on its own. If you want to stop it,
you can simply return {:stop, reason, state}
from any of the callback.
Link to this section Summary
Functions
Makes a synchronous call to the server and waits for its reply
Joins the topic
Returns true if the socket is joined on the given topic
Leaves the topic
Notifies the socket process that the connection has been established
Notifies the socket process about a disconnect
Forwards a received message to the socket process
Pushes a message to the topic
Can be invoked to send a response to the client
Starts the socket process
Callbacks
Invoked to handle a synchronous call
Invoked after the server closes a channel
Invoked after the client has successfully connected to the server
Invoked after the client has been disconnected from the server
Invoked to handle an Erlang message
Invoked if the server has refused a topic join request
Invoked after the client has successfully joined a topic
Invoked when a message from the server arrives
Invoked when the server replies to a message sent by the client
Invoked when the process is created
Link to this section Types
handler_response :: {:ok, callback_state} | {:connect, callback_state} | {:connect, url :: String.t, query_params, callback_state} | {:stop, reason :: any, callback_state}
socket_opts() :: [serializer: module, transport_opts: transport_opts]
Link to this section Functions
call(GenServer.server, any, non_neg_integer) :: any
Makes a synchronous call to the server and waits for its reply.
join(transport, topic, out_payload) :: {:ok, ref} | {:error, reason :: any}
Joins the topic.
Returns true if the socket is joined on the given topic.
This function should be invoked from the GenSocketClient
callback module.
leave(transport, topic, out_payload) :: {:ok, ref} | {:error, reason :: any}
Leaves the topic.
notify_connected(GenServer.server) :: :ok
Notifies the socket process that the connection has been established.
notify_disconnected(GenServer.server, any) :: :ok
Notifies the socket process about a disconnect.
notify_message(GenServer.server, binary) :: :ok
Forwards a received message to the socket process.
push(transport, topic, event, out_payload) :: {:ok, ref} | {:error, reason :: any}
Pushes a message to the topic.
Can be invoked to send a response to the client.
start_link(callback :: module, transport_mod :: module, any, socket_opts, GenServer.options) :: GenServer.on_start
Starts the socket process.
Link to this section Callbacks
handle_call(message :: any, GenServer.from, transport, callback_state) :: {:reply, reply, new_state} | {:reply, reply, new_state, timeout | :hibernate} | {:noreply, new_state} | {:noreply, new_state, timeout | :hibernate} | {:stop, reason, reply, new_state} | {:stop, reason, new_state} when new_state: callback_state, reply: term, reason: term
Invoked to handle a synchronous call.
handle_channel_closed(topic, payload, transport, callback_state) :: handler_response
Invoked after the server closes a channel.
handle_connected(transport, callback_state) :: handler_response
Invoked after the client has successfully connected to the server.
handle_disconnected(reason :: any, callback_state) :: handler_response
Invoked after the client has been disconnected from the server.
handle_info(message :: any, transport, callback_state) :: handler_response
Invoked to handle an Erlang message.
handle_join_error(topic, payload, transport, callback_state) :: handler_response
Invoked if the server has refused a topic join request.
handle_joined(topic, payload, transport, callback_state) :: handler_response
Invoked after the client has successfully joined a topic.
handle_message(topic, event, payload, transport, callback_state) :: handler_response
Invoked when a message from the server arrives.
handle_reply(topic, ref, payload, transport, callback_state) :: handler_response
Invoked when the server replies to a message sent by the client.
init(arg :: any) :: {:connect, url :: String.t, query_params, callback_state} | {:noconnect, url :: String.t, query_params, callback_state} | :ignore | {:error, reason :: any}
Invoked when the process is created.