summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2012-07-09 13:07:50 +0200
committerLoïc Hoguin <[email protected]>2012-07-09 13:13:36 +0200
commit6f17bb1455574012b4a15ad780585f964d85b7f9 (patch)
treee8069fd0b4ae58b6d01e8ce7570fb3246a9938e9
parentffde065f4b3a4f30738a172615f78de59a9c8490 (diff)
downloadbullet-6f17bb1455574012b4a15ad780585f964d85b7f9.tar.gz
bullet-6f17bb1455574012b4a15ad780585f964d85b7f9.tar.bz2
bullet-6f17bb1455574012b4a15ad780585f964d85b7f9.zip
Add a bullet clock example
-rw-r--r--examples/clock/README.md19
-rw-r--r--examples/clock/rebar.config4
-rw-r--r--examples/clock/src/clock.app.src15
-rw-r--r--examples/clock/src/clock.erl24
-rw-r--r--examples/clock/src/clock_app.erl33
-rw-r--r--examples/clock/src/clock_sup.erl23
-rw-r--r--examples/clock/src/stream_handler.erl36
-rw-r--r--examples/clock/src/toppage_handler.erl60
-rwxr-xr-xexamples/clock/start.sh3
9 files changed, 217 insertions, 0 deletions
diff --git a/examples/clock/README.md b/examples/clock/README.md
new file mode 100644
index 0000000..ff74862
--- /dev/null
+++ b/examples/clock/README.md
@@ -0,0 +1,19 @@
+Bullet Clock
+============
+
+To compile this example you need rebar in your PATH.
+
+Type the following command:
+```
+$ rebar get-deps compile
+```
+
+You can then start the Erlang node with the following command:
+```
+./start.sh
+```
+
+Then point your browser to the indicated URL.
+
+You can interrupt temporarily the node to check that Bullet
+properly reconnects when something happens.
diff --git a/examples/clock/rebar.config b/examples/clock/rebar.config
new file mode 100644
index 0000000..a254494
--- /dev/null
+++ b/examples/clock/rebar.config
@@ -0,0 +1,4 @@
+{deps, [
+ {bullet, ".*",
+ {git, "git://github.com/extend/bullet.git", "master"}}
+]}.
diff --git a/examples/clock/src/clock.app.src b/examples/clock/src/clock.app.src
new file mode 100644
index 0000000..e4d9f29
--- /dev/null
+++ b/examples/clock/src/clock.app.src
@@ -0,0 +1,15 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+{application, clock, [
+ {description, "Bullet clock example."},
+ {vsn, "1"},
+ {modules, []},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib,
+ cowboy
+ ]},
+ {mod, {clock_app, []}},
+ {env, []}
+]}.
diff --git a/examples/clock/src/clock.erl b/examples/clock/src/clock.erl
new file mode 100644
index 0000000..a4a2988
--- /dev/null
+++ b/examples/clock/src/clock.erl
@@ -0,0 +1,24 @@
+%% Copyright (c) 2012, Loïc Hoguin <[email protected]>
+%%
+%% Permission to use, copy, modify, and/or distribute this software for any
+%% purpose with or without fee is hereby granted, provided that the above
+%% copyright notice and this permission notice appear in all copies.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-module(clock).
+
+%% API.
+-export([start/0]).
+
+%% API.
+
+start() ->
+ ok = application:start(cowboy),
+ ok = application:start(clock).
diff --git a/examples/clock/src/clock_app.erl b/examples/clock/src/clock_app.erl
new file mode 100644
index 0000000..71de61f
--- /dev/null
+++ b/examples/clock/src/clock_app.erl
@@ -0,0 +1,33 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+%% @private
+-module(clock_app).
+-behaviour(application).
+
+%% API.
+-export([start/2]).
+-export([stop/1]).
+
+%% API.
+
+start(_Type, _Args) ->
+ Dispatch = [
+ {'_', [
+ {[], toppage_handler, []},
+ {[<<"bullet">>], bullet_handler, [{handler, stream_handler}]},
+ {[<<"static">>, '...'], cowboy_http_static, [
+ {directory, {priv_dir, bullet, []}},
+ {mimetypes, [
+ {<<".js">>, [<<"application/javascript">>]}
+ ]}
+ ]}
+ ]}
+ ],
+ {ok, _} = cowboy:start_listener(http, 100,
+ cowboy_tcp_transport, [{port, 8080}],
+ cowboy_http_protocol, [{dispatch, Dispatch}]
+ ),
+ clock_sup:start_link().
+
+stop(_State) ->
+ ok.
diff --git a/examples/clock/src/clock_sup.erl b/examples/clock/src/clock_sup.erl
new file mode 100644
index 0000000..abc2c3c
--- /dev/null
+++ b/examples/clock/src/clock_sup.erl
@@ -0,0 +1,23 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+%% @private
+-module(clock_sup).
+-behaviour(supervisor).
+
+%% API.
+-export([start_link/0]).
+
+%% supervisor.
+-export([init/1]).
+
+%% API.
+
+-spec start_link() -> {ok, pid()}.
+start_link() ->
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+%% supervisor.
+
+init([]) ->
+ Procs = [],
+ {ok, {{one_for_one, 10, 10}, Procs}}.
diff --git a/examples/clock/src/stream_handler.erl b/examples/clock/src/stream_handler.erl
new file mode 100644
index 0000000..4f18b9d
--- /dev/null
+++ b/examples/clock/src/stream_handler.erl
@@ -0,0 +1,36 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+%% @doc Stream handler for clock synchronizing.
+-module(stream_handler).
+
+-export([init/4]).
+-export([stream/3]).
+-export([info/3]).
+-export([terminate/2]).
+
+-define(PERIOD, 1000).
+
+init(_Transport, Req, _Opts, _Active) ->
+ io:format("bullet init~n"),
+ _ = erlang:send_after(?PERIOD, self(), refresh),
+ {ok, Req, undefined}.
+
+stream(<<"ping">>, Req, State) ->
+ io:format("ping received~n"),
+ {reply, <<"pong">>, Req, State};
+stream(Data, Req, State) ->
+ io:format("stream received ~s~n", [Data]),
+ {ok, Req, State}.
+
+info(refresh, Req, State) ->
+ _ = erlang:send_after(?PERIOD, self(), refresh),
+ DateTime = cowboy_clock:rfc1123(),
+ io:format("clock refresh timeout: ~s~n", [DateTime]),
+ {reply, DateTime, Req, State};
+info(Info, Req, State) ->
+ io:format("info received ~p~n", [Info]),
+ {ok, Req, State}.
+
+terminate(_Req, _State) ->
+ io:format("bullet terminate~n"),
+ ok.
diff --git a/examples/clock/src/toppage_handler.erl b/examples/clock/src/toppage_handler.erl
new file mode 100644
index 0000000..66c8400
--- /dev/null
+++ b/examples/clock/src/toppage_handler.erl
@@ -0,0 +1,60 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+%% @doc Main page of the clock application.
+-module(toppage_handler).
+
+-export([init/3]).
+-export([handle/2]).
+-export([terminate/2]).
+
+init(_Transport, Req, []) ->
+ {ok, Req, undefined}.
+
+handle(Req, State) ->
+ Body = <<"
+<!DOCTYPE html>
+<html lang=\"en\">
+<head>
+ <meta charset=\"utf-8\">
+ <title>Bullet Clock</title>
+</head>
+
+<body>
+ <p>Connection status: <span id=\"status\">bullet not started</span></p>
+ <p>Current time: <span id=\"time\">unknown</span></p>
+
+ <script
+ src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js\">
+ </script>
+ <script src=\"/static/bullet.js\"></script>
+ <script type=\"text/javascript\">
+// <![CDATA[
+$(document).ready(function(){
+ var bullet = $.bullet('ws://localhost:8080/bullet');
+ bullet.onopen = function(){
+ $('#status').text('online');
+ };
+ bullet.ondisconnect = function(){
+ $('#status').text('offline');
+ };
+ bullet.onmessage = function(e){
+ if (e.data != 'pong'){
+ $('#time').text(e.data);
+ }
+ };
+ bullet.onheartbeat = function(){
+ console.log('ping');
+ bullet.send('ping');
+ }
+});
+// ]]>
+ </script>
+</body>
+</html>
+">>,
+ {ok, Req2} = cowboy_http_req:reply(200, [{'Content-Type', <<"text/html">>}],
+ Body, Req),
+ {ok, Req2, State}.
+
+terminate(_Req, _State) ->
+ ok.
diff --git a/examples/clock/start.sh b/examples/clock/start.sh
new file mode 100755
index 0000000..5ccc3f8
--- /dev/null
+++ b/examples/clock/start.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+erl -pa ebin deps/*/ebin -s clock \
+ -eval "io:format(\"Point your browser at http://localhost:8080~n\")."