Browse Source

add websocket example

Pablo Vieytes 12 years ago
parent
commit
b8a0a8963b

+ 3 - 0
examples/README.md

@@ -28,3 +28,6 @@ Cowboy Examples
 
  *  [static](./examples/static):
     an example file server
+
+ *  [static](./examples/websocket):
+    websocket example

+ 17 - 0
examples/websocket/README.md

@@ -0,0 +1,17 @@
+Cowboy websocket
+================
+
+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 to open a websocket client. 
+Not all browsers suport websockets. It was tested with Chromium.

+ 108 - 0
examples/websocket/priv/html_ws_client.html

@@ -0,0 +1,108 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+    <title>Websocket client</title>
+    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
+    <script type="text/javascript">
+      
+      var websocket;
+      $(document).ready(init);
+      
+      function init() {
+          if(!("WebSocket" in window)){  
+              $('#status').append('<p><span style="color: red;">websockets are not supported </span></p>');
+              $("#navigation").hide();  
+          } else {
+              $('#status').append('<p><span style="color: green;">websockets are supported </span></p>');
+              connect();
+          };
+              $("#connected").hide(); 	
+              $("#content").hide(); 	
+      };
+
+      function connect()
+      {
+          wsHost = $("#server").val()
+          websocket = new WebSocket(wsHost);
+          showScreen('<b>Connecting to: ' +  wsHost + '</b>'); 
+          websocket.onopen = function(evt) { onOpen(evt) }; 
+          websocket.onclose = function(evt) { onClose(evt) }; 
+          websocket.onmessage = function(evt) { onMessage(evt) }; 
+          websocket.onerror = function(evt) { onError(evt) }; 
+      };  
+      
+      function disconnect() {
+          websocket.close();
+      }; 
+
+      function toggle_connection(){
+          if(websocket.readyState == websocket.OPEN){
+              disconnect();
+          } else {
+              connect();
+          };
+      };
+
+      function sendTxt() {
+          if(websocket.readyState == websocket.OPEN){
+              txt = $("#send_txt").val();
+              websocket.send(txt);
+              showScreen('sending: ' + txt); 
+          } else {
+               showScreen('websocket is not connected'); 
+          };
+      };
+
+      function onOpen(evt) { 
+          showScreen('<span style="color: green;">CONNECTED </span>'); 
+          $("#connected").fadeIn('slow');
+          $("#content").fadeIn('slow');
+      };  
+
+      function onClose(evt) { 
+          showScreen('<span style="color: red;">DISCONNECTED </span>');
+      };  
+
+      function onMessage(evt) { 
+          showScreen('<span style="color: blue;">RESPONSE: ' + evt.data+ '</span>'); 
+      };  
+
+      function showScreen(txt) { 
+          $('#output').prepend('<p>' + txt + '</p>');
+      };
+
+      function clearScreen() 
+      { 
+          $('#output').html("");
+      };
+    </script>
+  </head>
+
+  <body>
+    <div id="header">
+      <h1>Websocket client</h1>
+      <div id="status"></div>
+    </div>
+
+
+    <div id="navigation">
+
+      <p id="connecting">
+	<input type='text' id="server" value="ws://localhost:8080/websocket"></input>
+	<button type="button" onclick="toggle_connection()">connection</button>
+      </p>
+      <div id="connected">				
+	<p>
+	  <input type='text' id="send_txt" value=></input>
+	  <button type="button" onclick="sendTxt();">send</button>
+	</p>
+      </div>
+
+      <div id="content">						
+	<button id="clear" onclick="clearScreen()" >Clear text</button>
+	<div id="output"></div>
+      </div>
+
+    </div>
+  </body>
+</html> 

+ 4 - 0
examples/websocket/rebar.config

@@ -0,0 +1,4 @@
+{deps, [
+	{cowboy, ".*",
+		{git, "git://github.com/extend/cowboy.git", "master"}}
+]}.

+ 24 - 0
examples/websocket/src/toppage_handler.erl

@@ -0,0 +1,24 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+-module(toppage_handler).
+
+-export([init/3]).
+-export([handle/2]).
+-export([terminate/3]).
+
+init(_Transport, Req, []) ->
+	{ok, Req, undefined}.
+
+handle(Req, State) ->
+	Html = get_html(),
+	{ok, Req2} = cowboy_req:reply(200, [], Html, Req),
+	{ok, Req2, State}.
+
+terminate(_Reason, _Req, _State) ->
+	ok.
+
+get_html() ->
+	{ok, Cwd} = file:get_cwd(),
+	Filename =filename:join([Cwd, "priv", "html_ws_client.html"]),
+	{ok, Binary} = file:read_file(Filename),
+	Binary.

+ 15 - 0
examples/websocket/src/websocket.app.src

@@ -0,0 +1,15 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+{application, websocket, [
+	{description, "Cowboy websocket example."},
+	{vsn, "1"},
+	{modules, []},
+	{registered, []},
+	{applications, [
+		kernel,
+		stdlib,
+		cowboy
+	]},
+	{mod, {websocket_app, []}},
+	{env, []}
+]}.

+ 12 - 0
examples/websocket/src/websocket.erl

@@ -0,0 +1,12 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+-module(websocket).
+
+%% API.
+-export([start/0]).
+
+start() ->
+	ok = application:start(crypto),
+	ok = application:start(ranch),
+	ok = application:start(cowboy),
+	ok = application:start(websocket).

+ 24 - 0
examples/websocket/src/websocket_app.erl

@@ -0,0 +1,24 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+%% @private
+-module(websocket_app).
+-behaviour(application).
+
+%% API.
+-export([start/2]).
+-export([stop/1]).
+
+%% API.
+start(_Type, _Args) ->
+	Dispatch = cowboy_router:compile([
+		{'_', [
+			{"/", toppage_handler, []},
+			{"/websocket", ws_handler, []}
+		]}
+	]),
+	{ok, _} = cowboy:start_http(http, 100, [{port, 8080}], 
+		[{env, [{dispatch, Dispatch}]}]),
+	websocket_sup:start_link().
+
+stop(_State) ->
+	ok.

+ 23 - 0
examples/websocket/src/websocket_sup.erl

@@ -0,0 +1,23 @@
+%% Feel free to use, reuse and abuse the code in this file.
+
+%% @private
+-module(websocket_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}}.

+ 29 - 0
examples/websocket/src/ws_handler.erl

@@ -0,0 +1,29 @@
+-module(ws_handler).
+-behaviour(cowboy_websocket_handler).
+
+-export([init/3]).
+-export([websocket_init/3]).
+-export([websocket_handle/3]).
+-export([websocket_info/3]).
+-export([websocket_terminate/3]).
+
+init({tcp, http}, _Req, _Opts) ->
+	{upgrade, protocol, cowboy_websocket}.
+
+websocket_init(_TransportName, Req, _Opts) ->
+	erlang:start_timer(1000, self(), <<"Hello!">>),
+	{ok, Req, undefined_state}.
+
+websocket_handle({text, Msg}, Req, State) ->
+	{reply, {text, << "That's what she said! ", Msg/binary >>}, Req, State};
+websocket_handle(_Data, Req, State) ->
+	{ok, Req, State}.
+
+websocket_info({timeout, _Ref, Msg}, Req, State) ->
+	erlang:start_timer(1000, self(), <<"How' you doin'?">>),
+	{reply, {text, Msg}, Req, State};
+websocket_info(_Info, Req, State) ->
+	{ok, Req, State}.
+
+websocket_terminate(_Reason, _Req, _State) ->
+	ok.

+ 4 - 0
examples/websocket/start.sh

@@ -0,0 +1,4 @@
+#!/bin/sh
+erl -pa ebin deps/*/ebin -s websocket \
+    -eval "io:format(\"Point your browser at http://localhost:8080/ to use a simple websocket client~n\")."
+