NAME
Dancer::Tutorial::WebSockets - How to build WebSocket apps with Dancer
DESCRIPTION
This tutorial will demonstrate building a simple WebSocket enabled app using Dancer and Web::Hippie. WebSockets are what all the cook kids are talking about these days. They make it possible to create push based applications. Instead of polling a server repeatedly for updates, the server pushes data to you as soon as it is available. Given Dancer's "light core" philosophy, WebSockets are not built in. So we will use a Plack Middleware called Web::Hippie to do the hard work for us.
Example
For this example to work, you will need a recent version of Dancer installed. You will also need to install Plack, Web::Hippie and Twiggy. This example has only been tested on the Chrome web browser. Firefox does not support WebSockets by default as of the publication of this tutorial. This example requires 2 files. First, create ./wsdemo.pl:
#!/usr/bin/env perl
use Dancer;
use AnyMQ;
use Plack::Builder;
my $bus = AnyMQ->new;
my $topic = $bus->topic('demo');
get '/' => sub { template 'index' };
# Web::Hippie routes
get '/new_listener' => sub {
request->env->{'hippie.listener'}->subscribe($topic);
};
get '/message' => sub {
my $msg = request->env->{'hippie.message'};
$topic->publish($msg);
};
builder {
mount '/' => dance;
mount '/_hippie' => builder {
enable '+Web::Hippie';
enable '+Web::Hippie::Pipe', bus => $bus;
dance;
};
};
Now create the template file ./views/index.tt:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
var socket;
$(function() {
// ws_path should be of the form ws://host/_hippie/ws
var ws_path = "ws:<% request.base.opaque %>_hippie/ws";
socket = new WebSocket(ws_path);
socket.onopen = function() {
$('#connection-status').text("Connected");
};
socket.onmessage = function(e) {
var data = JSON.parse(e.data);
if (data.msg) {
var time = Date();
$('ul').prepend('<li>' + time + ': ' + data.msg + '</li>');
}
};
});
function send_msg(message) {
socket.send(JSON.stringify({ msg: message }));
}
</script>
</head>
<body>
<h1 id="title">Dancer WebSocket Demo</h1>
Connection Status:
<span id="connection-status"> Disconnected </span>
<div>
<input value="Send Message" type=button onclick="send_msg('hello')"/>
<input value="clear" type=button onclick="$('ul').empty()"/>
</div>
<span style="font-weight:bold"> Messages </span>
<ul id="list"></ul>
</body>
</html>
To test your app, just run:
plackup -s Twiggy wsdemo.pl
Now visit http://localhost:5000 in your browser. Clicking the Send Message button should add messages to the webpage. Open a second browser window and open the same url, http://localhost:5000. Clicking the Send Message button should add the same message to both windows.
REST Interface
You can interact with your app from external clients as well. Just add this route to your ./wsdemo.pl file right after the '/' route:
any '/send_msg' => sub {
$topic->publish({ msg => params->{msg} });
return "sent message\n";
};
Restart your application. Now you can send messages to your app with any http client:
$ curl -d msg=shalom http://localhost:5000/send_msg
Or
$ curl http://localhost:5000/send_msg?msg=salaam
Or just open the url http://localhost:5000/send_msg?msg=howdy in another browser window.