Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)
Post on 12-Jul-2015
300 Views
Preview:
Transcript
Mojolicious
Perl Framework for the Real-Time Web
Dotan Dimet@dotandimet
But that was a while back
Most People Moved on
Perl People
• But some came back
• And brought back cool ideas
Mojolicious
Mojolicious
Real Time Web
• Non-blocking I/O
• Event-driven code
• Asynchronous APIs
– Not mandatory
– Sometimes necessary
Features
Morbo error page
Hypnotoad error page
Exampleuse Mojolicious::Lite;
use 5.20.0;
use experimental 'signatures';
get '/' => {template => 'index'};
websocket '/title' => sub ($c) {
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
};
app->start;
__DATA__
@@ index.html.ep
% my $url = url_for 'title';
<script>
var ws = new WebSocket('<%= $url->to_abs %>');
ws.onmessage = function (event) { document.body.innerHTML += event.data };
ws.onopen = function (event) { ws.send('http://mojolicio.us') };
</script>
First Route:render a template
get '/' => {template => 'index'};
use Mojolicious::Lite;
use 5.20.0;
use experimental 'signatures';
get '/' => {template => 'index'};
websocket '/title' => sub ($c) {
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
};
app->start;
__DATA__
@@ index.html.ep
% my $url = url_for 'title';
<script>
var ws = new WebSocket('<%= $url->to_abs %>');
ws.onmessage = function (event) { document.body.innerHTML += event.data };
ws.onopen = function (event) { ws.send('http://mojolicio.us') };
</script>
Template (embedded Perl)
% my $url = url_for 'title';
<script>
var ws = new WebSocket('<%= $url->to_abs %>');
ws.onmessage = function (event) { document.body.innerHTML += event.data };
ws.onopen = function (event) { ws.send('http://mojolicio.us') };
</script>
Websocket Message Event
websocket '/title' => sub ($c) {
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
};
Event driven – subscribe to message event, triggered when complete message arrives
Websocket Message Event
websocket '/title' => sub ($c) {
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
};
• Send response when done
Built-in Web Client
websocket '/title' => sub ($c) {
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
};
Get a web page, parse into DOM, return the title text.
Web Client
• Mojo::UserAgent
– Blocking and non-blocking HTTP requests
• Mojo::DOM
– Supports most CSS selectors like jQuery
Web Client 2
• Get Haaretz.co.il full article text:self->ua->get( $url,
{ 'User-Agent' => 'Googlebot/2.1; +http://www.google.com/bot.html)' }
)->res->dom->find('#article-box p')->join("\n");
But this is blocking code!
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
When we trigger the message event, we block the event loop until we get a response from the web page
Sometimes blocking is OK
• Traditional Database connection
• Small apps, querying fast remote sites
But we don’t have to block
$c->ua->get($url, sub { ... });
The Mojo::UserAgent calls can take a callback to make non-blocking requests
Sometimes we can’t block
$c->ua->get($c->url_for(‘index’)->to_abs)
• For example, when demoing without internet, we want to fetch a web page we are serving from the same process...
More
• http://mojolicio.us
• http://mojocasts.com
– Glen Hinkle @tempire
• (I stole the nice slides from him)
• irc irc://irc.perl.org/#mojo
• mailing list mojolicious@googlegroups.com
use Mojolicious::Lite;
use 5.20.0;
use experimental 'signatures';
get '/' => {template => 'index'};
websocket '/title' => sub ($c) {
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
};
app->start;
__DATA__
@@ index.html.ep
% my $url = url_for 'title';
<script>
var ws = new WebSocket('<%= $url->to_abs %>');
ws.onmessage = function (event) { document.body.innerHTML += event.data };
ws.onopen = function (event) { ws.send('http://mojolicio.us') };
</script>
Signaturesuse Mojolicious::Lite;
Use 5.20.0;
Use experimental 'signatures';
get '/' => {template => 'index'};
websocket '/title' => sub ($c) {
$c->on(message => sub ($c, $msg) {
my $title = $c->ua->get($msg)->res->dom->at('title')->text;
$c->send($title);
});
};
app->start;
__DATA__
@@ index.html.ep
% my $url = url_for 'title';
<script>
var ws = new WebSocket('<%= $url->to_abs %>');
ws.onmessage = function (event) { document.body.innerHTML += event.data };
ws.onopen = function (event) { ws.send('http://mojolicio.us') };
</script>
top related