Skip to content

Instantly share code, notes, and snippets.

@omarkj
Created March 21, 2012 10:21
Show Gist options
  • Save omarkj/2146000 to your computer and use it in GitHub Desktop.
Save omarkj/2146000 to your computer and use it in GitHub Desktop.
websocket_handler
%% Feel free to use, reuse and abuse the code in this file.
-module(websocket_handler).
-behaviour(cowboy_http_handler).
-behaviour(cowboy_http_websocket_handler).
-export([init/3, handle/2, terminate/2]).
-export([websocket_init/3, websocket_handle/3,
websocket_info/3, websocket_terminate/3]).
-record(state, {counter = 0,
timeout_ref}).
init({_Any, http}, Req, []) ->
case cowboy_http_req:header('Upgrade', Req) of
{undefined, Req2} -> {ok, Req2, undefined};
{<<"websocket">>, _Req2} -> {upgrade, protocol, cowboy_http_websocket};
{<<"WebSocket">>, _Req2} -> {upgrade, protocol, cowboy_http_websocket}
end.
handle(Req, State) ->
{ok, Req2} = cowboy_http_req:reply(200, [{'Content-Type', <<"text/html">>}],
%% HTML code taken from misultin's example file.
<<"<html>
<head>
<script type=\"text/javascript\">
function addStatus(text){
var date = new Date();
document.getElementById('status').innerHTML
= document.getElementById('status').innerHTML
+ date + \": \" + text + \"<br/>\";
}
function ready(){
if (\"MozWebSocket\" in window) {
WebSocket = MozWebSocket;
}
if (\"WebSocket\" in window) {
// browser supports websockets
var ws = new WebSocket(\"ws://localhost:8080/websocket\");
ws.onopen = function() {
// websocket is connected
addStatus(\"websocket connected!\");
// send hello data to server.
ws.send(\"hello server!\");
addStatus(\"sent message to server: 'hello server'!\");
};
ws.onmessage = function (evt) {
var receivedMsg = evt.data;
addStatus(\"server sent the following: '\" + receivedMsg + \"'\");
};
ws.onclose = function() {
// websocket was closed
addStatus(\"websocket was closed\");
};
} else {
// browser does not support websockets
addStatus(\"sorry, your browser does not support websockets.\");
}
}
</script>
</head>
<body onload=\"ready();\">
Hi!
<div id=\"status\"></div>
</body>
</html>">>, Req),
{ok, Req2, State}.
terminate(_Req, _State) ->
ok.
websocket_init(_Any, Req, []) ->
timer:send_interval(500, he),
Req2 = cowboy_http_req:compact(Req),
Ref = create_counter(5000, ping, #state{timeout_ref=undefined}),
io:format("Ref is ~p~n", [Ref]),
{ok, Req2, #state{counter=0,
timeout_ref=Ref}}.
websocket_handle({text, Msg}, Req, State) ->
{reply, {text, Msg}, Req, State};
websocket_handle({pong, Msg}, Req, State) ->
io:format("Got pong ~p~n", [Msg]),
{ok, Req, State#state{timeout_ref=create_counter(5000, ping, State)}};
websocket_handle(_Any, Req, State) ->
{ok, Req, State}.
websocket_info(he, Req, #state{counter=Counter}=State) ->
{reply, {text, <<"catch sys:(pid(0,3507,43)).catch sys:(pid(0,3507,43)).catch sys:(pid(0,3507,43)).catch sys:(pid(0,3507,43)).catch sys:(pid(0,3507,43)).catch sys:(pid(0,3507,43)).catch sys:(pid(0,3507,43)).">>}, Req, State#state{counter=Counter+1}};
websocket_info(ping, Req, #state{counter=Counter}=State) ->
io:format("Going to ping ~p~n", [Counter]),
{reply, {ping, create_ping(Counter)}, Req, State#state{counter=Counter+1,
timeout_ref=create_counter(5000, pong, State)}};
websocket_info(pong, Req, State) ->
io:format("Client didn't reply in time I GO~n"),
{shutdown, Req, State};
websocket_info(_Info, Req, State) ->
{ok, Req, State, hibernate}.
websocket_terminate(_Reason, _Req, _State) ->
ok.
create_ping(Counter) ->
list_to_binary(integer_to_list(Counter)).
create_counter(Timeout, Msg, #state{timeout_ref=TimeoutRef}) ->
timer:cancel(TimeoutRef),
{ok, Ref} = timer:send_after(Timeout, Msg),
Ref.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment