Phoenix.Socket.Transport

Parsed documentation:
View on GitHub
Outlines the Socket <-> Transport communication.

This module specifies a behaviour that all sockets must implement.
`Phoenix.Socket` is just one possible implementation of a socket
that multiplexes events over multiple channels. Developers can
implement their own sockets as long as they implement the behaviour
outlined here.

Developers interested in implementing custom transports must invoke
the socket API defined in this module. This module also provides
many conveniences to make it easier to build custom transports.

## Workflow

Whenever your endpoint starts, it will automatically invoke the
`child_spec/1` on each listed socket and start that specification
under the endpoint supervisor. For this reason, custom transports
that are manually started in the supervision tree must be listed
after the endpoint.

Whenever the transport receives a connection, it should invoke the
`c:connect/1` callback with a map of metadata. Different sockets may
require different metadatas.

If the connection is accepted, the transport can move the connection
to another process, if so desires, or keep using the same process. The
process responsible for managing the socket should then call `c:init/1`.

For each message received from the client, the transport must call
`c:handle_in/2` on the socket. For each informational message the
transport receives, it should call `c:handle_info/2` on the socket.

On termination, `c:terminate/2` must be called. A special atom with
reason `:closed` can be used to specify that the client terminated
the connection.

## Example

Here is a simple pong socket implementation:

    defmodule PingSocket do
      @behaviour Phoenix.Socket.Transport

      def child_spec(opts) do
        # We won't spawn any process, so let's return a dummy task
        %{id: Task, start: {Task, :start_link, [fn -> :ok end]}, restart: :transient}
      end

      def connect(map) do
        # Callback to retrieve relevant data from the connection.
        # The map contains options, params, transport and endpoint keys.
        {:ok, state}
      end

      def init(state) do
        # Now we are effectively inside the process that maintains the socket.
        {:ok, state}
      end

      def handle_in({"ping", _opts}, state) do
        {:reply, :ok, {:text, "pong"}, state}
      end

      def handle_info(_, state) do
        {:ok, state}
      end

      def terminate(_reason, _state) do
        :ok
      end
    end

It can be mounted in your endpoint like any other socket:

    socket "/socket", PingSocket, websocket: true, longpoll: true

You can now interact with the socket under `/socket/websocket`
and `/socket/longpoll`.

## Security

This module also provides functions to enable a secure environment
on transports that, at some point, have access to a `Plug.Conn`.

The functionality provided by this module helps in performing "origin"
header checks and ensuring only SSL connections are allowed.
No suggestions.
Please help! Open an issue on GitHub if this assessment is incorrect.