real-time web apps - meetupfiles.meetup.com/501101/real time web apps.pdfwhy real-time? • 2 or...
TRANSCRIPT
Real-Time Web AppsMaking web apps that respond like desktop apps.
What is a real-time web app?
The user is given the latest information without refreshing their browser.
Why real-time?
Why real-time?• 2 or more people working on the same thing
(Google Docs)
Why real-time?• 2 or more people working on the same thing
(Google Docs)
• 2 or more people share a goal (games)
Why real-time?• 2 or more people working on the same thing
(Google Docs)
• 2 or more people share a goal (games)
• 2 or more people communicating (chat, forums)
Why real-time?• 2 or more people working on the same thing
(Google Docs)
• 2 or more people share a goal (games)
• 2 or more people communicating (chat, forums)
• presence indicators (Facebook)
Why real-time?• 2 or more people working on the same thing
(Google Docs)
• 2 or more people share a goal (games)
• 2 or more people communicating (chat, forums)
• presence indicators (Facebook)
• letting the user know about things that affect them (background jobs, other users actions)
How it works
Browser 1Rest
Server
Real Time ServerBrowser 2
How it works
Browser 1Rest
Server
Real Time ServerBrowser 2
Subscribe
Subscribe
How it works
Browser 1Rest
Server
Real Time ServerBrowser 2
Subscribe
Subscribe
Methods
• Short polling
• Long polling (aka Comet)
• Web sockets
Short Polling
• Browser asks the server for new info every few seconds.
• Hits the server hard.
Browser
Rest Server
Short Polling
• Browser asks the server for new info every few seconds.
• Hits the server hard.
Browser
Rest Server
Long Polling (Comet)
• Browser asks the server for new info, but waits on the server for a response.
• Immediately re-establishes connection after response.
• Assumes a long HTTP timeout.
Browser
Rest Server
Long Polling (Comet)
• Browser asks the server for new info, but waits on the server for a response.
• Immediately re-establishes connection after response.
• Assumes a long HTTP timeout.
Browser
Rest Server
Are we there yet?
Web Sockets
• Browser establishes a connection with the server, and now has bidirectional communication.
• Requires async web app, and web-sockets enabled server.
Browser
Socket Server
Web Sockets
• Browser establishes a connection with the server, and now has bidirectional communication.
• Requires async web app, and web-sockets enabled server.
Browser
Socket Server
Web Sockets
• Browser establishes a connection with the server, and now has bidirectional communication.
• Requires async web app, and web-sockets enabled server.
Browser
Socket Server
But wait! There’s more!
Hybrid Rest/Socket
• App doesn’t have to be async.
• Separation of concerns.
• Offload the load.
• If browser isn’t subscribed it will miss messages.
Browser
Rest Server
Socket Server
Hybrid Rest/Socket
• App doesn’t have to be async.
• Separation of concerns.
• Offload the load.
• If browser isn’t subscribed it will miss messages.
Browser
Rest Server
Socket Server
Hybrid Rest/Socket
• App doesn’t have to be async.
• Separation of concerns.
• Offload the load.
• If browser isn’t subscribed it will miss messages.
Browser
Rest Server
Socket Server
Hybrid With Data Store
• Browsers don’t need to be connected right now to receive messages.
• Won’t lose data between page views.
• If not deleted, have archive of data.
Browser
Rest Server
Socket Server
Data Store
Hybrid With Data Store
• Browsers don’t need to be connected right now to receive messages.
• Won’t lose data between page views.
• If not deleted, have archive of data.
Browser
Rest Server
Socket Server
Data Store
Implementations• MeteorServer.org
• Firehose.io
• PubNub.com
• Pusher.com
• Firebase.com
• Dancer::Plugin::WebSocket
• Socket.io
• Mojolicio.us
• Web::Hippie
• Plack::MiddleWare::SocketIO
• And a bajillion more!
Implementations• MeteorServer.org
• Firehose.io
• PubNub.com
• Pusher.com
• Firebase.com
• Dancer::Plugin::WebSocket
• Socket.io
• Mojolicio.us
• Web::Hippie
• Plack::MiddleWare::SocketIO
Firehose.io
Firehose.io
• Open source
Firehose.io
• Open source
• Has its own JS library
Firehose.io
• Open source
• Has its own JS library
• Use LWP or REST::Client to connect
Firehose.io
• Open source
• Has its own JS library
• Use LWP or REST::Client to connect
• Stores data in Redis or RabbitMQ
Firehose.io
• Open source
• Has its own JS library
• Use LWP or REST::Client to connect
• Stores data in Redis or RabbitMQ
• Starts web sockets, degrades to long polling
Firehose.iouse HTTP::Tiny;use JSON;
my $message = {type => ‘error’,data => ‘Something bad happened.’
}
HTTP::Tiny->new->post(‘http://localhost:7474/notifications’,encode_json($message)
);
Firehose.io<script src="/firehose.js"></script>
new Firehose.Consumer({uri : ‘http://localhost:7474/notifications’,message : function(message) {
if (message.type == ‘error’) {alert(message.data);
}}
});
use HTTP::Tiny;use JSON;
my $message = {type => ‘error’,data => ‘Something bad happened.’
}
HTTP::Tiny->new->post(‘http://localhost:7474/notifications’,encode_json($message)
);
Pusher.com
Pusher.com• Hosted service, free for
development
Pusher.com• Hosted service, free for
development
• Nice debugging console
Pusher.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
Pusher.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
• WWW::Pusher for Perl
Pusher.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
• WWW::Pusher for Perl
• No data storage
Pusher.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
• WWW::Pusher for Perl
• No data storage
• Starts web sockets, degrades to long polling
Pusher.comuse WWW::Pusher;
my $pusher = WWW::Pusher->new(channel => ‘notifications’
);
$pusher->trigger( event => ‘error’, data => ‘Something bad happened.’);
Pusher.com<script src="http://js.pusher.com/2.1/pusher.min.js"></script>
var pusher = new Pusher();var channel = pusher.subscribe(‘notifications’);
channel.bind(‘error’, function(data) {alert(data);
});
use WWW::Pusher;
my $pusher = WWW::Pusher->new(channel => ‘notifications’
);
$pusher->trigger( event => ‘error’, data => ‘Something bad happened.’);
Demohttp://pusher.com/tutorials/realtime_chat_widget
Firebase.com
Firebase.com• Hosted service, free for
development
Firebase.com• Hosted service, free for
development
• Nice debugging console
Firebase.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
Firebase.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
• Firebase for Perl
Firebase.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
• Firebase for Perl
• Abundant data storage
Firebase.com• Hosted service, free for
development
• Nice debugging console
• Has its own JS library
• Firebase for Perl
• Abundant data storage
• Starts web sockets, degrades to long polling
Firebase.comuse Firebase;
my $firebase = Firebase->new(firebase => ‘jt’
);
$firebase->put(‘notifications’, { type => ‘error’, data => ‘Something bad happened.’});
Firebase.com<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
var notifications = new Firebase('https://jt.firebaseIO.com/notifications');
notifications.on('child_added', function(message) { if (message.val().type == ‘error’) { alert(message.val().data); }});
use Firebase;
my $firebase = Firebase->new(firebase => ‘jt’
);
$firebase->put(‘notifications’, { type => ‘error’, data => ‘Something bad happened.’});
Demohttps://www.firebase.com/docs/examples.html
Dancer::Plugin::WebSocket
Dancer::Plugin::WebSocket
• Open source
Dancer::Plugin::WebSocket
• Open source
• Pure Perl
Dancer::Plugin::WebSocket
• Open source
• Pure Perl
• Roll your own
Dancer::Plugin::WebSocket
• Open source
• Pure Perl
• Roll your own
• Has its own JS library
Dancer::Plugin::WebSocket
• Open source
• Pure Perl
• Roll your own
• Has its own JS library
• Can store to any message queue
Dancer::Plugin::WebSocket
• Open source
• Pure Perl
• Roll your own
• Has its own JS library
• Can store to any message queue
• Web sockets only
Dancer::Plugin::WebSocketuse Dancer;use Dancer::Plugin::WebSocket;
dance;
Dancer::Plugin::WebSocket
var ws_path = "ws://localhost:5000/_hippie/ws"; var socket = new WebSocket(ws_path); socket.onopen = function() { document.getElementById('conn-status').innerHTML = 'Connected'; }; socket.onmessage = function(e) { var data = JSON.parse(e.data); if (data.msg) console.log(data.msg); }; function send_msg(message) { socket.send(JSON.stringify({ msg: message })); }
use Dancer;use Dancer::Plugin::WebSocket;
dance;
Demo
Web::Hippie
Web::Hippie
• Open source
Web::Hippie
• Open source
• Pure Perl
Web::Hippie
• Open source
• Pure Perl
• Roll your own
Web::Hippie
• Open source
• Pure Perl
• Roll your own
• Has its own JS library
Web::Hippie
• Open source
• Pure Perl
• Roll your own
• Has its own JS library
• Can store to any message queue
Web::Hippie
• Open source
• Pure Perl
• Roll your own
• Has its own JS library
• Can store to any message queue
• Web sockets only
Sound FamiliarThat’s because Web::Hippie is the foundation of
Dancer::Plugin::WebSocket
Demo
The Real World
NotificationsSales, reviews, approvals, order processing.
Firebase
Seller’sBrowser
Wing Socket Server
Data Store
Wingman
Buyer’sBrowser
Firebase
Seller’sBrowser
Wing Socket Server
Data Store
Wingman
Buyer’sBrowser
Firebase
Seller’sBrowser
Wing Socket Server
Data Store
Wingman
Buyer’sBrowser
Large Upload HandlingTake in the file, analyze it, thumb nail it, and upload it to
S3.
Browser
Wing Socket Server
Data Store
WingmanFirebase
Browser
Wing Socket Server
Data Store
WingmanFirebase
Browser
Wing Socket Server
Data Store
WingmanFirebase
ChatLet users talk to each other on the site.
Firebase
User 2’sBrowser
Socket Server
Data Store
User 1’sBrowser
Maintains Chat History
Firebase
User 2’sBrowser
Socket Server
Data Store
User 1’sBrowser
Maintains Chat History
@omgtcid thecaptainisdeadomgtcid
EverythingPlayer movement, interaction with the map,
communication, etc.
Very Early Pre-Alpha
Pusher
Player 2Browser
Wing Socket Server
Player 1Browser
Pusher
Player 2Browser
Wing Socket Server
Player 1Browser
Pusher
Player 2Browser
Wing Socket Server
Player 1Browser
Pusher
Player 2Browser
Wing Socket Server
Player 1Browser
No data store needed because of
command log.
What have we learned?
What have we learned?
• Provides a better user experience.
What have we learned?
• Provides a better user experience.
• Reduces the load on the server.
What have we learned?
• Provides a better user experience.
• Reduces the load on the server.
• Makes hard things possible.
What have we learned?
• Provides a better user experience.
• Reduces the load on the server.
• Makes hard things possible.
• Can be used in any web app.
What have we learned?
• Provides a better user experience.
• Reduces the load on the server.
• Makes hard things possible.
• Can be used in any web app.
• Lots of ways to implement it.
What have we learned?
• Provides a better user experience.
• Reduces the load on the server.
• Makes hard things possible.
• Can be used in any web app.
• Lots of ways to implement it.
• Relatively easy to do.
Questions?