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

Returns true if the socket is joined on the given 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

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

Link to this type callback_state() View Source
callback_state() :: any
Link to this type encoded_message() View Source
encoded_message() :: binary
Link to this type handler_response() View Source
handler_response ::
  {:ok, callback_state} |
  {:connect, callback_state} |
  {:connect, url :: String.t, query_params, callback_state} |
  {:stop, reason :: any, callback_state}
Link to this type message() View Source
message() :: term
Link to this type out_payload() View Source
out_payload() :: %{optional(String.t | atom) => any}
Link to this type payload() View Source
payload() :: %{optional(String.t) => any}
Link to this type query_params() View Source
query_params() :: [{String.t, String.t}]
Link to this type ref() View Source
ref() :: pos_integer
Link to this type socket_opts() View Source
socket_opts() :: [serializer: module, transport_opts: transport_opts]
Link to this type transport_opts() View Source
transport_opts() :: any

Link to this section Functions

Link to this function call(server, request, timeout \\ 5000) View Source
call(GenServer.server, any, non_neg_integer) :: any

Makes a synchronous call to the server and waits for its reply.

Link to this function join(transport, topic, payload \\ %{}) View Source
join(transport, topic, out_payload) ::
  {:ok, ref} |
  {:error, reason :: any}

Joins the topic.

Link to this function joined?(topic) View Source
joined?(topic) :: boolean

Returns true if the socket is joined on the given topic.

This function should be invoked from the GenSocketClient callback module.

Link to this function leave(transport, topic, payload \\ %{}) View Source
leave(transport, topic, out_payload) ::
  {:ok, ref} |
  {:error, reason :: any}

Leaves the topic.

Link to this function notify_connected(socket) View Source
notify_connected(GenServer.server) :: :ok

Notifies the socket process that the connection has been established.

Link to this function notify_disconnected(socket, reason) View Source
notify_disconnected(GenServer.server, any) :: :ok

Notifies the socket process about a disconnect.

Link to this function notify_message(socket, message) View Source
notify_message(GenServer.server, binary) :: :ok

Forwards a received message to the socket process.

Link to this function push(transport, topic, event, payload) View Source
push(transport, topic, event, out_payload) ::
  {:ok, ref} |
  {:error, reason :: any}

Pushes a message to the topic.

Link to this function reply(from, response) View Source
reply(GenServer.from, any) :: :ok

Can be invoked to send a response to the client.

Link to this function start_link(callback, transport_mod, arg, socket_opts \\ [], gen_server_opts \\ []) View Source
start_link(callback :: module, transport_mod :: module, any, socket_opts, GenServer.options) :: GenServer.on_start

Starts the socket process.

Link to this section Callbacks

Link to this callback handle_call(message, arg1, transport, callback_state) View Source
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.

Link to this callback handle_channel_closed(topic, payload, transport, callback_state) View Source
handle_channel_closed(topic, payload, transport, callback_state) :: handler_response

Invoked after the server closes a channel.

Link to this callback handle_connected(transport, callback_state) View Source
handle_connected(transport, callback_state) :: handler_response

Invoked after the client has successfully connected to the server.

Link to this callback handle_disconnected(reason, callback_state) View Source
handle_disconnected(reason :: any, callback_state) :: handler_response

Invoked after the client has been disconnected from the server.

Link to this callback handle_info(message, transport, callback_state) View Source
handle_info(message :: any, transport, callback_state) :: handler_response

Invoked to handle an Erlang message.

Link to this callback handle_join_error(topic, payload, transport, callback_state) View Source

Invoked if the server has refused a topic join request.

Link to this callback handle_joined(topic, payload, transport, callback_state) View Source

Invoked after the client has successfully joined a topic.

Link to this callback handle_message(topic, event, payload, transport, callback_state) View Source

Invoked when a message from the server arrives.

Link to this callback handle_reply(topic, ref, payload, transport, callback_state) View Source

Invoked when the server replies to a message sent by the client.

Link to this callback init(arg) View Source
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.