Phoenix v1.2.1 Phoenix.Socket.Transport behaviour
API for building transports.
This module describes what is required to build a Phoenix transport. The transport sits between the socket and channels, forwarding client messages to channels and vice-versa.
A transport is responsible for:
- Implementing the transport behaviour
- Establishing the socket connection
- Handling of incoming messages
- Handling of outgoing messages
- Managing channels
- Providing secure defaults
The transport behaviour
The transport requires two functions:
default_config/0
- returns the default transport configuration to be merged when the transport is declared in the socket modulehandlers/0
- returns a map of handlers. For example, if the transport can be run cowboy, it just need to specify the appropriate cowboy handler
Socket connections
Once a connection is established, the transport is responsible
for invoking the Phoenix.Socket.connect/2
callback and acting
accordingly. Once connected, the transport should request the
Phoenix.Socket.id/1
and subscribe to the topic if one exists.
On subscribed, the transport must be able to handle “disconnect”
broadcasts on the given id topic.
The connect/6
function in this module can be used as a
convenience or a documentation on such steps.
Incoming messages
Incoming messages are encoded in whatever way the transport
chooses. Those messages must be decoded in the transport into a
Phoenix.Socket.Message
before being forwarded to a channel.
Most of those messages are user messages except by:
- “heartbeat” events in the “phoenix” topic - should just emit an OK reply
- “phx_join” on any topic - should join the topic
- “phx_leave” on any topic - should leave the topic
The function dispatch/3
can help with handling of such messages.
Outgoing messages
Channels can send two types of messages back to a transport:
Phoenix.Socket.Message
and Phoenix.Socket.Reply
. Those
messages are encoded in the channel into a format defined by
the transport. That’s why transports are required to pass a
serializer that abides to the behaviour described in
Phoenix.Transports.Serializer
.
Managing channels
Because channels are spawned from the transport process, transports
must trap exits and correctly handle the {:EXIT, _, _}
messages
arriving from channels, relaying the proper response to the client.
The following events are sent by the transport when a channel exits:
"phx_close"
- The channel has exited gracefully"phx_error"
- The channel has crashed
The on_exit_message/3
function aids in constructing these messages.
Duplicate Join Subscriptions
For a given topic, the client may only establish a single channel
subscription. When attempting to create a duplicate subscription,
dispatch/3
will close the existing channel, log a warning, and
spawn a new channel for the topic. When sending the "phx_close"
event form the closed channel, the message will contain the ref
the
client sent when joining. This allows the client to uniquely identify
"phx_close"
and "phx_error"
messages when force-closing a channel
on duplicate joins.
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 help with doing “origin” header checks and ensuring only SSL connections are allowed.
Remote Client
Channels can reply, synchronously, to any handle_in/3
event. To match
pushes with replies, clients must include a unique ref
with every
message and the channel server will reply with a matching ref where
the client and pick up the callback for the matching reply.
Phoenix includes a JavaScript client for WebSocket and Longpolling support using JSON encodings.
However, a client can be implemented for other protocols and encodings by
abiding by the Phoenix.Socket.Message
format.
Protocol Versioning
Clients are expected to send the Channel Transport protocol version that they
expect to be talking to. The version can be retrieved on the server from
Phoenix.Channel.Transport.protocol_version/0
. If no version is provided, the
Transport adapters should default to assume a "1.0.0"
version number.
See web/static/js/phoenix.js
for an example transport client
implementation.
Summary
Functions
Checks the origin request header against the list of allowed origins
Handles the socket connection
Dispatches Phoenix.Socket.Message
to a channel
Forces SSL in the socket connection
Returns the message to be relayed when a channel exists
Returns the Channel Transport protocol version
Logs the transport request
Callbacks
Provides a keyword list of default configuration for socket transports
Functions
Checks the origin request header against the list of allowed origins.
Should be called by transports before connecting when appropriate. If the origin header matches the allowed origins, no origin header was sent or no origin was configured, it will return the given connection.
Otherwise a otherwise a 403 Forbidden response will be sent and the connection halted. It is a noop if the connection has been halted.
Handles the socket connection.
It builds a new Phoenix.Socket
and invokes the handler
connect/2
callback and returns the result.
If the connection was successful, generates Phoenix.PubSub
topic from the id/1
callback.
Dispatches Phoenix.Socket.Message
to a channel.
All serialized, remote client messages should be deserialized and forwarded through this function by adapters.
The following returns must be handled by transports:
:noreply
- Nothing to be done by the transport{:reply, reply}
- The reply to be sent to the client{:joined, channel_pid, reply}
- The channel was joined and the reply must be sent as result{:error, reason, reply}
- An error happened and the reply must be sent as result
Parameters filtering on join
When logging parameters, Phoenix can filter out sensitive parameters
in the logs, such as passwords, tokens and what not. Parameters to
be filtered can be added via the :filter_parameters
option:
config :phoenix, :filter_parameters, ["password", "secret"]
With the configuration above, Phoenix will filter any parameter
that contains the terms password
or secret
. The match is
case sensitive.
Phoenix’s default is ["password"]
.
Forces SSL in the socket connection.
Uses the endpoint configuration to decide so. It is a noop if the connection has been halted.
Callbacks
Specs
default_config :: Keyword.t
Provides a keyword list of default configuration for socket transports.