phoenix_gen_socket_client v4.0.0 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.
Returns a specification to start this module under a supervisor.
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.
Optional callback invoked when the server is about to exit. It should do any cleanup required.
Link to this section Types
Specs
callback_state() :: any()
Specs
encoded_message() :: binary()
Specs
event() :: String.t()
Specs
handler_response() :: {:ok, callback_state()} | {:connect, callback_state()} | {:connect, url :: String.t(), query_params(), callback_state()} | {:stop, reason :: any(), callback_state()}
Specs
message() :: term()
Specs
Specs
Specs
Specs
ref() :: pos_integer()
Specs
socket_opts() :: [serializer: module(), transport_opts: transport_opts()]
Specs
topic() :: String.t()
Specs
transport()
Specs
transport_opts() :: any()
Link to this section Functions
Specs
call(GenServer.server(), any(), timeout()) :: any()
Makes a synchronous call to the server and waits for its reply.
Returns a specification to start this module under a supervisor.
See Supervisor
.
Specs
join(transport(), topic(), out_payload()) :: {:ok, ref()} | {:error, reason :: any()}
Joins the topic.
Specs
Returns true if the socket is joined on the given topic.
This function should be invoked from the GenSocketClient
process.
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(), {:text | :binary, binary()}) :: :ok
Forwards a received message to the socket process.
Specs
Pushes a message to the topic.
Specs
reply(GenServer.from(), any()) :: :ok
Can be invoked to send a response to the client.
start_link(callback, transport_mod, arg, socket_opts \\ [], gen_server_opts \\ [])
View SourceSpecs
start_link( callback :: module(), transport_mod :: module(), any(), socket_opts(), GenServer.options() ) :: GenServer.on_start()
Starts the socket process.
Link to this section Callbacks
Specs
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.
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(), query_params(), callback_state()} | {:noconnect, url :: String.t(), query_params(), callback_state()} | :ignore | {:error, reason :: any()}
Invoked when the process is created.
Specs
Optional callback invoked when the server is about to exit. It should do any cleanup required.