README.md

# Sock

[![Build Status](https://github.com/mtrudel/sock/workflows/Elixir%20CI/badge.svg)](https://github.com/mtrudel/sock/actions)
[![Docs](https://img.shields.io/badge/api-docs-green.svg?style=flat)](https://hexdocs.pm/sock)
[![Hex.pm](https://img.shields.io/hexpm/v/sock.svg?style=flat&color=blue)](https://hex.pm/packages/sock)


Sock is a specification for apps to service WebSocket connections; you can think
of it as 'Plug for WebSockets'. Web servers such as
[Bandit](https://github.com/mtrudel/bandit/) or
[Cowboy](https://github.com/ninenines/cowboy) are expected to implement support
for hosting Sock-based applications (possibly by way of an adapter library such
as [Plug.Cowboy](https://github.com/elixir-plug/plug_cowboy/)). WebSocket-aware
applications such as Phoenix can then be hosted within a supported web server
simply by defining conformance to the `Sock` behaviour, in the same manner as
how Plug conformance allows their HTTP aspects to be hosted within an arbitrary
web server.

The Sock specification is just that; a specification. There is no actual *code*
in this specification as there is within the Plug specification, largely due to
the lower-level nature of WebSockets as compared to HTTP. What you *will* find
here consists of a few interfaces along with conventions as to how they reflect
the lifecycle of a WebSocket connection:

* The `Sock` behaviour describes the functions that an application must
  implement in order to be Sock compliant; it is the equivalent of the `Plug`
  interface, but for WebSocket connections. Server implementations are expected
  to allow users to define which user-provided module is to be used as the `Sock`
  implementation for a given server, in a manner similar to `Plug`.
* The `Socket` protocol describes a mechanism for Sock applications to send data
  to a connected WebSocket client. It is the equivalent of the `Plug.Conn`
  interface, but for WebSocket connections. Server implementations are expected
  to provide a concrete implementation of this protocol for whichever type is
  passed in to `Sock` calls as the socket value.

The above is intended primarily as a high-level overview to provide a conceptual
understanding of how all the building blocks of `Sock` fit together. For more
information, consult the [docs](https://hexdocs.pm/sock).

## WebSocket Lifecycle

WebSocket connections go through a well defined lifecycle, which is reflected in
the shape of the `Sock` behaviour:

* First, a client will attempt to Upgrade an HTTP connection to a WebSocket
  connection by passing a specific set of headers in an HTTP request. A `Sock`
  implementation is notified of this via a call to `c:Sock.negotiate/2`. The
  implementation can inspect the request, which is passed as a `Plug.Conn`
  structure. It can then choose to accept or refuse the WebSocket upgrade
  request
* Assuming the `Sock` implementation accepted the WebSocket connection, the
  HTTP connection is then upgraded to a WebSocket connection, and
  `c:Sock.handle_connection/2` is called to notify the implementation that the
  connection is now live
* The `Sock` implementation will then be notified of client data by way of
  `c:Sock.handle_text_frame/3`, `c:Sock.handle_binary_frame/3`,
  `c:Sock.handle_ping_frame/3` or `c:Sock.handle_pong_frame/3` as appropriate.
* The `Sock` implementation is free to send data to the client via the passed in
  `Socket` instance at any time
* At any time, `c:Sock.handle_close/3`, `c:Sock.handle_error/3` or
  `c:Sock.handle_timeout/2` may be called to indicate a close, error or timeout
  condition respectively

## Installation

The sock package can be installed by adding `sock` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:sock, "~> 0.2.5"}
  ]
end
```

Documentation can be found at <https://hexdocs.pm/sock>.

## License

MIT