dshaw-talk-2012-07-nodeconf
Version:
More Realtime
427 lines (338 loc) • 12 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>More Realtime - @dshaw</title>
<meta name="description" content="More Realtime with Node.js.">
<meta name="author" content="Daniel D. Shaw - @dshaw">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/print.css" type="text/css" media="print">
<link rel="stylesheet" href="lib/zenburn.css">
<style type="text/css">
#reveal section img.experience,
#reveal section img.noborder {
border: 0px
}
#reveal h1, #reveal h2, #reveal h3, #reveal h4 {
margin-top: 40px
}
.thelist {
font-size: 1.6em;
line-height: 1.6em;
}
.lilpad {
padding: 2em;
}
</style>
</head>
<body>
<div id="reveal">
<!-- Used to fade in a background when a specific slide state is reached -->
<div class="state-background"></div>
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<!-- Title slide -->
<section>
<section>
<h1>More Realtime</h1>
<p class="intro">
<img class=avatar src="./assets/angry_unicorn.png">
</p>
<h3 class="inverted">@dshaw</h3>
<script>
// Delicously hacky. Look away.
if (navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/i)) document.write('<p style="color: rgba(0,0,0,0.3); text-shadow: none;">(' + 'Tap to navigate' + ')</p>');
</script>
</section>
<section>
<h1>MOAR Realtime!</h1>
<p class="intro">
<img class=avatar src="./assets/angry_unicorn.png">
</p>
<h3 class="inverted">@dshaw</h3>
</section>
<section>
<h1>More Socket.io</h1>
<p class="intro">
<img class=avatar src="./assets/angry_unicorn.png">
</p>
<h3 class="inverted">@dshaw</h3>
</section>
<section>
<h1>Way More Redis!</h1>
<p class="intro">
<img class=avatar src="./assets/angry_unicorn.png">
</p>
<h3 class="inverted">@dshaw</h3>
</section>
</section>
<!-- 3 Things -->
<section>
<h1>3 Things</h1>
<ol class="thelist">
<li>RedisStore Docs</li>
<li>Socket.io-Announce</li>
<li class="fragment">?</li>
</ol>
</section>
<!-- RedisStore Docs -->
<section>
<section>
<h2>Socket.io RedisStore</h2>
<p><img src="./assets/redis.png" class="lilpad"></p>
<p>That's awesome.</p>
</section>
<section>
<h2>Socket.io RedisStore</h2>
<h3>You know what's cooler than one process<br>
(or even a cluster of processes)?</h3>
<p>A cluster of servers.</p>
</section>
<section>
<h2>Socket.io RedisStore</h2>
<ul>
<li>
<p>Lightweight key/value persistence in Redis.</p>
<pre><code>
io.sockets.on('connection', function(socket) {
var nick = 'dshaw'
socket.set('nickname', nick, function() {
socket.emit('nickname', nick)
})
})
</code></pre>
</li>
<li>
<p>Inter-process dispatch.</p>
<pre><code>
io.sockets.emit('newuser', { nick: nick });
</code></pre>
</li>
</ul>
</section>
<section>
<h2>Socket.io RedisStore</h2>
<p>Cool. But how?</p>
<p><img src="./assets/deal_with_it.gif" style="padding: 0 4em"></p>
<p>Up until today, <abbr title="your on your own">YOYO</abbr>!</p>
</section>
<section>
<h2>RedisStore Docs</h2>
<h3>
<a href="https://github.com/dshaw/RedisStore-Docs">github.com/dshaw/RedisStore-Docs</a>
</h3>
<p><img src="./assets/thumbsup.png" style="width: 300px"></p>
</section>
</section>
<!-- Socket.io-announce -->
<section>
<section>
<h2>Socket.io-Announce</h2>
<h3>Network connected realtime services</h3>
<!--<p>Now that you have network connected realtime services in your infrastructure, what can you do?</p>-->
<p><img src="./assets/socketioannounce.png" style="width: 40%; background-color: #EEE; background: rgba(0, 0, 0, 0.1);"></p>
</section>
<section>
<h2>Traditional Socket.io</h2>
<h3>Tied to a web server</h3>
<p>Applies to the old school:<br>
Express + Socket.io</p>
<p>As it does to the newest:<br>
Tako</p>
</section>
<section>
<h2>Socket.io-Announce</h2>
<h3>Look ma, no server</h3>
<p>Just drop in Announce and broadcast data<br>
directly with your Socket.io connected users!</p>
</section>
<section>
<h2>Socket.io-Announce</h2>
<pre><code>
var announce = require('socket.io-announce').createClient()
, symbols = 'THOO GOOF EXIT BOP SDD ALPP RIGM OPPL HPBG'.split(' ')
function dataStream () {
var n = Math.round(Math.random()*8)
, data = {
id: (Math.abs(Math.random() * Math.random() * Date.now() | 0))
, symbol: symbols[n]
, price: (Math.random()*1000).toFixed(2)
, n: n
}
announce.emit('quote', data)
}
setInterval(dataStream, 800)
</code></pre>
</section>
<section>
<h2>Elsewhere, Socket.io Server</h2>
<pre><code>
var sio = require('socket.io')
, RedisStore = sio.RedisStore
, app = connect.createServer(connect.static(path.join(__dirname, './')))
, settings = { store: new RedisStore({
nodeId: function () { return 'socketio-1' }
}) }
, io = sio.listen(app, settings);
app.listen(port);
</code></pre>
</section>
<section>
<h2>Socket.io Client-side</h2>
<pre><code>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect()
socket.on('quote', function (data) {
$('<span/>', {
id: data.id,
html: data.symbol + ' : ' + data.price }).appendTo('#ticker')
// if the last digit of the prices matches the id, buy.
var m = ((data.price).match(/[-+]?([0-9]*([0-9]))?\.[0-9]+/))
, watch = m && m[2];
if (nodeId && watch == nodeId) {
$('#'+data.id).addClass('reserved')
data.buyer = nodeId
data.quantity = Math.round(Math.random()*5)*5
socket.emit('purchase', data)
}
});
</script>
</code></pre>
</section>
<section>
<h2>Socket.io-Announce</h2>
<h3><a href="https://github.com/dshaw/socket.io-announce">github.com/dshaw/socket.io-announce</a></h3>
<p>Insanely simple.</p>
</section>
</section>
<!-- 3 Things - REVEAL -->
<section>
<h1>3 Things</h1>
<ol class="thelist">
<li>RedisStore Docs</li>
<li>Socket.io-Announce</li>
<li class="fragment">Redis Monitor</li>
</ol>
</section>
<!-- Redis Monitor -->
<section>
<section>
<h2>Redis is Awesome</h2>
<p><img src="./assets/redis-small.png" style="padding: 2em"></p>
<p>You know that.</p>
</section>
<section>
<h2>RedisLive</h2>
<p>Monitoring with MONITOR is bad.</p>
<p>The MONITOR command is good and useful for debugging, but not monitoring.</p>
<h3><a href="http://redis.io/commands/monitor">redis.io/commands/monitor</a></h3>
</section>
<section>
<h2>Redis Monitor</h2>
<p>Monitor a single Redis or a cluster of Redis servers.</p>
<p>Now visualize what's going on on those servers.</p>
<p><img src="./assets/redis-monitor-screenshot.png" style="width: 60%"></p>
</section>
<section>
<h2>Redis Monitor</h2>
<h3>Use All The Things</h3>
<ol>
<li>Socket.io RedisStore</li>
<li>Socket.io-Announce</li>
</ol>
</section>
<section>
<h2>Redis Monitor</h2>
<h3><a href="https://github.com/dshaw/redis-monitor">github.com/dshaw/redis-monitor</a></h3>
<h3>Demo time!</h3>
</section>
</section>
<section>
<section>
<h1>One More Thing</h1>
<p><img src="./assets/jobs.jpg" class="lilpad"></p>
</section>
<section>
<h1>More, More Realtime</h1>
<ul>
<li>
<b>Socket.io-Zero</b><br>
ZeroMQ dispatch and Redis k/v<br>
<a href="https://github.com/dshaw/socket.io-zero">github.com/dshaw/socket.io-zero</a>
<br>
<br>
</li>
<li>
<b>Socket.io-Mongo</b><br>
MongoDB store with Mubsub dispatch<br>
<a href="https://github.com/kof/socket.io-mongo">github.com/kof/socket.io-mongo</a>
</li>
<!--<li>-->
<!--<b>Mubsub</b><br>-->
<!--Pub/sub for Node.js and MongoDB<br>-->
<!--<a href="https://github.com/scttnlsn/mubsub">github.com/scttnlsn/mubsub</a>-->
<!--</li>-->
</ul>
</section>
</section>
<section>
<h1>Thank you!</h1>
<h3 class="inverted">@dshaw</h3>
<p>More at: <a href="http://github.com/dshaw">github.com/dshaw</a></p>
</section>
</div>
<!-- The navigational controls UI -->
<aside class="controls">
<a class="left" href="#">◄</a>
<a class="right" href="#">►</a>
<a class="up" href="#">▲</a>
<a class="down" href="#">▼</a>
</aside>
<!-- Displays presentation progress, max value changes via JS to reflect # of slides -->
<div class="progress"><span></span></div>
</div>
<script src="js/reveal.js"></script>
<!-- Optional libraries for code syntax highlighting and classList support in IE9 -->
<script src="lib/highlight.js"></script>
<script src="lib/classList.js"></script>
<script>
// Parse the query string into a key/value object
var query = {};
location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
} );
// Fires when a slide with data-state=customevent is activated
Reveal.addEventListener( 'customevent', function() {
alert( '"customevent" has fired' );
} );
// Fires each time a new slide is activated
Reveal.addEventListener( 'slidechanged', function( event ) {
// event.indexh & event.indexv
} );
Reveal.initialize({
// Display controls in the bottom right corner
controls: true,
// Display a presentation progress bar
progress: true,
// If true; each slide will be pushed to the browser history
history: true,
// Loops the presentation, defaults to false
loop: false,
// Flags if mouse wheel navigation should be enabled
mouseWheel: true,
// Apply a 3D roll to links on hover
rollingLinks: true,
// UI style
theme: query.theme || 'default', // default/neon
// Transition style
transition: query.transition || 'default' // default/cube/page/concave/linear(2d)
});
hljs.initHighlightingOnLoad();
</script>
</body>
</html>