   alias Phoenix.Socket.Message
 
   @moduledoc """
+  The Transport Layer handles dispatching incoming and outgoing Channel
+  `%Message{}`'s from remote clients, backed by different Channel transport
+  implementations and serializations.
+
+  ## The Transport Adapter Contract
+
+  ### Server
+
+  To implement a Transport adapter, the Server must broker the following actions:
+
+    * Handle receiving incoming, encoded `%Message{}`'s from remote clients, then
+      deserialing and fowarding message through `Transport.dispatch/2`. Finish by
+      keeping state of returned `%Socket{}`.
+    * Handle receiving outgoing `%Message{}`s as Elixir process messages, then
+      encoding and fowarding to connected remote client.
+    * Handle receiving arbitrary Elixir messages and fowarding through
+      `Transport.dispatch_info/2`. Finish by keeping state of returned `%Socket{}`.
+    * Handle remote client disconnects and relaying event through
+      `Transport.dispatch_leave/2`
+
+  See `Phoenix.Transports.WebSocket` for an example transport server implementation.
+
+
+  ### Remote Client
+
+  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 `%Message{}` protocol as explained in `Phoenix.Message` docs.
+
+  See `assets/cs/phoenix.coffee` for an example transport client implementation.
   """
 
   defmodule InvalidReturn do

  end


  def dispatch(msg, socket) do
    socket
    |> Socket.set_current_channel(msg.channel, msg.topic)

    """
  end

  @doc """
  Arbitrary Elixir processes are received by adapters and forwarded through
  this function to be dispatched as `"info"` events on each socket channel.

  The returned `%Socket{}`'s state must be held by the adapter
  """
  def dispatch_info(socket = %Socket{},  data) do
    socket = Enum.reduce socket.channels, socket, fn {channel, topic}, socket ->
      {:ok, socket} = dispatch_info(socket, channel, topic, data)
