phoenix_gen_socket_client v1.0.0 Phoenix.Channels.GenSocketClient behaviour
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.
Summary
Functions
Joins the 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
Starts the socket process
Callbacks
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
Types
callback_state :: any
encoded_message :: binary
handler_response ::
{:ok, callback_state} |
{:connect, callback_state} |
{:stop, reason :: any, callback_state}
out_payload :: %{optional(String.t | atom) => any}
ref :: pos_integer
socket_opts :: [serializer: module, transport_opts: transport_opts]
transport_opts :: any
Functions
Specs
join(transport, topic, out_payload) ::
{:ok, ref} |
{:error, reason :: any}
Joins the topic.
Specs
leave(transport, topic, out_payload) ::
{:ok, ref} |
{:error, reason :: any}
Leaves the topic.
Specs
notify_connected(GenServer.server) :: :ok
Notifies the socket process that the connection has been established.
Specs
notify_disconnected(GenServer.server, any) :: :ok
Notifies the socket process about a disconnect.
Specs
notify_message(GenServer.server, binary) :: :ok
Forwards a received message to the socket process.
Specs
push(transport, topic, event, out_payload) ::
{:ok, ref} |
{:error, reason :: any}
Pushes a message to the topic.
Specs
start_link(callback :: module, transport_mod :: module, any, socket_opts, GenServer.options) :: GenServer.on_start
Starts the socket process.
Callbacks
Specs
handle_channel_closed(topic, payload, transport, callback_state) :: handler_response
Invoked after the server closes a channel.
Specs
handle_connected(transport, callback_state) :: handler_response
Invoked after the client has successfully connected to the server.
Specs
handle_disconnected(reason :: any, callback_state) :: handler_response
Invoked after the client has been disconnected from the server.
Specs
handle_info(message :: any, transport, callback_state) :: handler_response
Invoked to handle an Erlang message.
Specs
handle_join_error(topic, payload, transport, callback_state) :: handler_response
Invoked if the server has refused a topic join request.
Specs
handle_joined(topic, payload, transport, callback_state) :: handler_response
Invoked after the client has successfully joined a topic.
Specs
handle_message(topic, event, payload, transport, callback_state) :: handler_response
Invoked when a message from the server arrives.
Specs
handle_reply(topic, ref, payload, transport, callback_state) :: handler_response
Invoked when the server replies to a message sent by the client.
Specs
init(arg :: any) ::
{:connect, url :: String.t, callback_state} |
{:noconnect, url :: String.t, callback_state} |
:ignore |
{:error, reason :: any}
Invoked when the process is created.