Permalink
Browse files

Shored up the documentation

  • Loading branch information...
1 parent 828f79c commit 69d9722d9f1b8b7823ff0af5d6c9957a5b9fe304 @jeregrine committed Feb 22, 2014
Showing with 53 additions and 16 deletions.
  1. +51 −14 lib/phoenix/controller/websocket.ex
  2. +2 −2 lib/phoenix/examples/controller.ex
@@ -9,6 +9,7 @@ defmodule Phoenix.Controller.Websocket do
use Phoenix.Router
websocket "echo", Websocket
end
+
defmodule Websocket do
use Phoenix.Controller.Websocket
def receive(conn, data, state) do
@@ -17,53 +18,84 @@ defmodule Phoenix.Controller.Websocket do
end
There are 4 callbacks you can override to handle the common functions of a websocket.
- start(conn, state)
- receive(data, conn, state)
+ start(transport, req, opts)
+ stream(data, conn, state)
info(data, conn, state)
closed(data, conn, state)
- Each function is an alias for the websocket handler functions, for more information on connections and
- what you should return from these functions check out the websocket documentation.
-
+ Each function is an alias for the websocket handler functions, for more detailed information on
+ connections and what you should return from these functions check out the cowboy websocket documentation.
+ http://ninenines.eu/docs/en/cowboy/HEAD/manual/cowboy_websocket_handler/
+ Things to keep in mind:
+ * Connections will die quite often for any number of reasons. Keep your session and state data in another process.
+ * This is a raw websocket and it may make sense to look into more robust solutions such as [bullet](https://github.com/extend/bullet)
"""
- defmacro __using__(state \\ []) do
+ defmacro __using__(opts \\ []) do
+
+ transport = Dict.get(opts, :transport, :tcp)
+ unless transport in [:tcp, :ssl] do
+ raise "Websocket transport needs to be :tcp or :ssl. Please refer to websocket documentation."
+ end
+
quote location: :keep do
@behaviour :cowboy_websocket_handler
@doc false
- def init({:tcp, :http}, _req, _opts) do
- {:upgrade, :protocol, :cowboy_websocket}
+ def init({unquote(transport), :http}, req, opts) do
+ {:upgrade, :protocol, :cowboy_websocket, req, opts}
end
@doc false
def websocket_init(transport, req, opts) do
start(transport, req, opts)
end
+
@doc """
Handles initalization of the websocket, default implementation returns
{:ok, req, :undefined_state}
+ Possible returns:
+ {:ok, req, state}
+ {:ok, req, state, :hibernate} # To tell the websocket to hibernate
+ {:ok, req, state, timeout} # Timeout defines how long it waits for activity from the client. Default: infinity.
+ {:ok, req, state, timeout, :hibernate}
+ {:shutdown, req} # Shut the socket down before upgrading.
"""
def start(_transport, req, _opts) do
{:ok, req, :undefined_state}
end
@doc """
Handles handles recieving data from the client, default implementation does nothing.
-
+ {:ok, req, state}
+ Possible returns:
+ {:ok, req, state}
+ {:ok, req, state, :hibernate} # Do nothing and hibernate
+ {:reply, out_frame, req, state} # Reply to the client.
+ {:reply, out_frame, req, state, :hibernate} # Reply and hibernate connection
+ {:shutdown, req, state} # Terminate connection
+
+ out_frame is defined as:
+ :close | :ping | :pong
+ {:text | :binary | :close | :ping | :pong, iodata()}
+ {:close, close_code(), iodata()}
+
+ close_code: 1000..4999
"""
- def receive(data, req, state) do
+ def stream(data, req, state) do
{:ok, req, state}
end
@doc false
def websocket_handle(data, req, state) do
- receive(data, req, state)
+ stream(data, req, state)
end
@doc """
- Handles handles recieving messages from erlang processes.
+ Handles handles recieving messages from erlang processes. Default returns
+ {:ok, state}
+ Possible Returns are identical to stream, all replies gets send to the client.
"""
def info(conn, info, state) do
{:ok, state}
@@ -76,17 +108,22 @@ defmodule Phoenix.Controller.Websocket do
@doc """
This is called right before the websocket is about to be closed.
+ Reason is defined as:
+ {:normal, :shutdown | :timeout} # Called when erlang closes connection
+ {:remote, :closed} # Called if the client formally closes connection
+ {:remote, close_code(), binary()}
+ {:error, :badencoding | :badframe | :closed | atom()} # Called for many reasons: tab closed, connection dropped.
"""
def closed(_reason, req, state) do
- {:ok, state}
+ :ok
end
@doc false
def websocket_terminate(reason, req, state) do
closed(reason, req, state)
end
- defoverridable [start: 3, receive: 3, info: 3, closed: 3]
+ defoverridable [start: 3, stream: 3, info: 3, closed: 3]
end
end
end
@@ -59,7 +59,7 @@ end
defmodule Phoenix.Examples.Controllers.Echo do
use Phoenix.Controller.Websocket
- def receive(conn, data, _state) do
- conn.send(data)
+ def stream(data, req, state) do
+ {:reply, {:text, data}, req, state}
end
end

0 comments on commit 69d9722

Please sign in to comment.