In previous post Fixing an example in Mojolicious I bragged about
how fixing a small issue in an example makes me feel part of the
community. By the way, I think you should participate in the community
and brag about it too!
I was looking at that example because I was interested into the
EventSource API for a small project involving a game, rolling some
dice on the web and being able to play at a distance with physical stuff
(apart from the dice, of course). Hopefully more on this in the future.
#!/usr/bin/env perluse5.024;useMojolicious::Lite-signatures;packageSequenceEmitter{useMojo::Base'Mojo::EventEmitter','-signatures';useexperimentalqw< postderef >;nowarningsqw< experimental::postderef >;hassequence=>sub {[__rand()]};sub __rand{returnscalarintrand100}sub update($self) {my$v=__rand;push$self->sequence->@*,$v;$self->emit(push=>$v);}sub onboard_controller($self, $c) {my$method=sub ($e, $v) {$c->write("event:push\ndata: $v\n\n")};$method->($self,$self->sequence->[-1]);# send latest availablemy$cb=$self->on(push=>$method);# subscribe$c->on(finish=>sub ($c) {$self->unsubscribe(push=>$cb)});}}# Template 'index' with browser-side codeget'/box/:id'=>sub ($c) {return$c->render(template=>'index',id=>scalar$c->param('id'));};get'/tickle/:id'=>sub ($c) {emitter_for($c->param('id'))->update;return$c->render(text=>"OK\n");};get'/events/:id'=>sub ($c) {# Increase inactivity timeout for connection a bit$c->inactivity_timeout(300);# Change content type and finalize response headers$c->res->headers->content_type('text/event-stream');$c->write;emitter_for($c->param('id'))->onboard_controller($c);};app->start;sub emitter_for($id) {state%emitter_for;return$emitter_for{$id}//=SequenceEmitter->new;}__DATA__@@ index.html.ep<!DOCTYPE html><html> <head><title>LiveLog</title></head> <body> <script> var events = new EventSource('<%= url_for '/events' %>/<%= $id %>'); events.addEventListener('push', function (event) { document.body.innerHTML += event.data + '<br/>'; }, false); </script> </body></html>
I guess you know how to start it, so I won’t bother you here.
After the program is started, you can try it on the local host like
this:
decide a name for your box, for example foo
point a couple of browser windows to
http://127.0.0.1:3000/box/foo - you
should see that a number between 0 and 99 (included) is shown in both
(the same number);
use another browser window, or a command line curl command, to
trigger the generation of a new value using url
http://127.0.0.1/tickle/foo - you
should see it appear in both windows
open another browser window to
http://127.0.0.1:3000/box/foo - you
should just see the last number that was generated in it
If you use bar instead of foo you will look into a different
box… with a different sequence of numbers.
I know, I know… I should have used a POST and not a GET… but it’s a
proof of concept!