Mojolicious - Perl Framework for the Real-Time Web (Lightning Talk)

Post on 12-Jul-2015

300 Views

Category:

Software

3 Downloads

Preview:

Click to see full reader

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