WebSockex behaviour (WebSockex v0.4.3) View Source

A client handles negotiating the connection, then sending frames, receiving frames, closing, and reconnecting that connection.

A simple client implementation would be:

defmodule WsClient do
  use WebSockex

  def start_link(url, state) do
    WebSockex.start_link(url, __MODULE__, state)
  end

  def handle_frame({:text, msg}, state) do
    IO.puts "Received a message: #{msg}"
    {:ok, state}
  end

  def handle_cast({:send, {type, msg} = frame}, state) do
    IO.puts "Sending #{type} frame with payload: #{msg}"
    {:reply, frame, state}
  end
end

Supervision

WebSockex is implemented as an OTP Special Process and as a result will fit into supervision trees.

WebSockex also supports the Supervisor children format introduced in Elixir 1.5. Meaning that a child specification could be {ClientModule, [state]}.

However, since there is a possibility that you would like to provide a t:WebSockex.Conn/0 or a url as well as the state, there are two versions of the child_spec function. If you need functionality beyond that it is recommended that you override the function or define your own.

Just remember to use the version that corresponds with your start_link's arity.

Link to this section Summary

Types

An integer between 1000 and 4999 that specifies the reason for closing the connection.

The error returned when a connection fails to be established.

The frame sent when the negotiating a connection closure.

The reason a connection was closed.

A map that contains information about the failure to connect.

Debug options to be parsed by :sys.debug_options/1.

Options values for start_link.

Callbacks

Invoked when a new version the module is loaded during runtime.

Invoked to retrieve a formatted status of the state in a WebSockex process.

Invoked to handle asynchronous cast/2 messages.

Invoked after a connection is established.

Invoked when the WebSocket disconnects from the server.

Invoked on the reception of a frame on the socket.

Invoked to handle all other non-WebSocket messages.

Invoked when the Websocket receives a ping frame

Invoked when the Websocket receives a pong frame.

Invoked when the process is terminating.

Link to this section Types

Specs

client() :: pid() | atom() | {:via, module(), term()} | {:global, term()}

Specs

close_code() :: integer()

An integer between 1000 and 4999 that specifies the reason for closing the connection.

Specs

close_error() ::
  %WebSockex.RequestError{__exception__: term(), code: term(), message: term()}
  | %WebSockex.ConnError{__exception__: term(), original: term()}
  | %WebSockex.InvalidFrameError{__exception__: term(), frame: term()}
  | %WebSockex.FrameEncodeError{
      __exception__: term(),
      close_code: term(),
      frame_payload: term(),
      frame_type: term(),
      reason: term()
    }

The error returned when a connection fails to be established.

Specs

close_frame() :: {close_code(), message :: binary()}

The frame sent when the negotiating a connection closure.

Specs

close_reason() ::
  {:remote | :local, :normal}
  | {:remote | :local, close_code(), message :: binary()}
  | {:remote, :closed}
  | {:error, term()}

The reason a connection was closed.

A :normal reason is the same as a 1000 reason with no payload.

If the peer closes the connection abruptly without a close frame then the close reason is {:remote, :closed}.

Link to this type

connection_status_map()

View Source

Specs

connection_status_map() :: %{
  reason: close_reason() | close_error(),
  attempt_number: integer(),
  conn: WebSockex.Conn.t()
}

A map that contains information about the failure to connect.

This map contains the error, attempt number, and the WebSockex.Conn.t/0 that was used to attempt the connection.

Specs

debug_opts() :: [
  :trace
  | :log
  | {:log, log_depth :: pos_integer()}
  | :statistics
  | {:log_to_file, Path.t()}
]

Debug options to be parsed by :sys.debug_options/1.

These options can also be set after the process is running using the functions in the Erlang :sys module.

Specs

frame() ::
  :ping
  | :pong
  | {:ping | :pong, nil | (message :: binary())}
  | {:text | :binary, message :: binary()}

Specs

option() ::
  WebSockex.Conn.connection_option()
  | {:async, boolean()}
  | {:debug, debug_opts()}
  | {:name, atom() | {:global, term()} | {:via, module(), term()}}
  | {:handle_initial_conn_failure, boolean()}

Options values for start_link.

  • :async - Replies with {:ok, pid} before establishing the connection. This is useful for when attempting to connect indefinitely, this way the process doesn't block trying to establish a connection.
  • :handle_initial_conn_failure - When set to true a connection failure while establishing the initial connection won't immediately return an error and instead will invoke the handle_disconnect/2 callback. This option only matters during process initialization. The handle_disconnect callback is always invoked if an established connection is lost.
  • :debug - Options to set the debug options for :sys.handle_debug.
  • :name - An atom that the registers the process with name locally. Can also be a {:via, module, term} or {:global, term} tuple.

Other possible option values include: WebSockex.Conn.connection_option/0

Specs

options() :: [option()]

Link to this section Functions

Specs

cast(client(), term()) :: :ok

Asynchronously sends a message to a client that is handled by handle_cast/2.

Link to this function

handle_terminate_close(reason, parent, debug, state)

View Source

Specs

handle_terminate_close(any(), pid(), any(), any()) :: no_return()
Link to this function

init(parent, name, conn, module, module_state, opts)

View Source

Specs

init(pid(), atom(), WebSockex.Conn.t(), module(), term(), options()) ::
  {:ok, pid()} | {:error, term()}
Link to this function

send_frame(client, frame)

View Source

Specs

send_frame(client(), frame()) ::
  :ok
  | {:error,
     %WebSockex.FrameEncodeError{
       __exception__: term(),
       close_code: term(),
       frame_payload: term(),
       frame_type: term(),
       reason: term()
     }
     | %WebSockex.ConnError{__exception__: term(), original: term()}
     | %WebSockex.NotConnectedError{
         __exception__: term(),
         connection_state: term()
       }
     | %WebSockex.InvalidFrameError{__exception__: term(), frame: term()}}
  | none()

Sends a frame through the WebSocket.

If the connection is either connecting or closing then this will return an error tuple with a WebSockex.NotConnectedError exception struct as the second element.

If a connection failure is discovered while sending then it will return an error tuple with a WebSockex.ConnError exception struct as the second element.

Link to this function

start(conn_info, module, state, opts \\ [])

View Source

Specs

start(url :: String.t() | WebSockex.Conn.t(), module(), term(), options()) ::
  {:ok, pid()} | {:error, term()}

Starts a WebSockex process.

Acts like start_link/4, except doesn't link the current process.

See start_link/4 for more information.

Link to this function

start_link(conn_info, module, state, opts \\ [])

View Source

Specs

start_link(url :: String.t() | WebSockex.Conn.t(), module(), term(), options()) ::
  {:ok, pid()} | {:error, term()}

Starts a WebSockex process linked to the current process.

For available option values see option/0.

If a WebSockex.Conn.t is used in place of a url string, then the options available in WebSockex.Conn.connection_option/0 have effect.

The callback handle_connect/2 is invoked after the connection is established.

Link to this section Callbacks

Link to this callback

code_change(old_vsn, state, extra)

View Source

Specs

code_change(
  old_vsn :: term() | {:down, term()},
  state :: term(),
  extra :: term()
) :: {:ok, new_state :: term()} | {:error, reason :: term()}

Invoked when a new version the module is loaded during runtime.

Link to this callback

format_status(atom, list)

View Source (optional)

Specs

format_status(:normal, [process_dictionary | state]) :: status :: term()
when process_dictionary: [{key :: term(), val :: term()}], state: term()

Invoked to retrieve a formatted status of the state in a WebSockex process.

This optional callback is used when you want to edit the values returned when invoking :sys.get_status.

The second argument is a two-element list with the order of [pdict, state].

Specs

handle_cast(msg :: term(), state :: term()) ::
  {:ok, new_state}
  | {:reply, frame(), new_state}
  | {:close, new_state}
  | {:close, close_frame(), new_state}
when new_state: term()

Invoked to handle asynchronous cast/2 messages.

Link to this callback

handle_connect(conn, state)

View Source

Specs

handle_connect(conn :: WebSockex.Conn.t(), state :: term()) ::
  {:ok, new_state :: term()}

Invoked after a connection is established.

This is invoked after both the initial connection and a reconnect.

Link to this callback

handle_disconnect(connection_status_map, state)

View Source

Specs

handle_disconnect(connection_status_map(), state :: term()) ::
  {:ok, new_state}
  | {:reconnect, new_state}
  | {:reconnect, new_conn :: WebSockex.Conn.t(), new_state}
when new_state: term()

Invoked when the WebSocket disconnects from the server.

This callback is only invoked in the event of a connection failure. In cases of crashes or other errors the process will terminate immediately skipping this callback.

If the handle_initial_conn_failure: true option is provided during process startup, then this callback will be invoked if the process fails to establish an initial connection.

If a connection is established by reconnecting, the handle_connect/2 callback will be invoked.

The possible returns for this callback are:

  • {:ok, state} will continue the process termination.
  • {:reconnect, state} will attempt to reconnect instead of terminating.
  • {:reconnect, conn, state} will attempt to reconnect with the connection data in conn. conn is expected to be a WebSockex.Conn.t/0.
Link to this callback

handle_frame(frame, state)

View Source

Specs

handle_frame(frame(), state :: term()) ::
  {:ok, new_state}
  | {:reply, frame(), new_state}
  | {:close, new_state}
  | {:close, close_frame(), new_state}
when new_state: term()

Invoked on the reception of a frame on the socket.

The control frames have possible payloads, when they don't have a payload then the frame will have nil as the payload. e.g. {:ping, nil}

Specs

handle_info(msg :: term(), state :: term()) ::
  {:ok, new_state}
  | {:reply, frame(), new_state}
  | {:close, new_state}
  | {:close, close_frame(), new_state}
when new_state: term()

Invoked to handle all other non-WebSocket messages.

Link to this callback

handle_ping(ping_frame, state)

View Source

Specs

handle_ping(ping_frame :: :ping | {:ping, binary()}, state :: term()) ::
  {:ok, new_state}
  | {:reply, frame(), new_state}
  | {:close, new_state}
  | {:close, close_frame(), new_state}
when new_state: term()

Invoked when the Websocket receives a ping frame

Link to this callback

handle_pong(pong_frame, state)

View Source

Specs

handle_pong(pong_frame :: :pong | {:pong, binary()}, state :: term()) ::
  {:ok, new_state}
  | {:reply, frame(), new_state}
  | {:close, new_state}
  | {:close, close_frame(), new_state}
when new_state: term()

Invoked when the Websocket receives a pong frame.

Link to this callback

terminate(close_reason, state)

View Source

Specs

terminate(close_reason(), state :: term()) :: any()

Invoked when the process is terminating.