Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
WebSockets (confoo)
Search
Igor Wiedler
March 02, 2012
Programming
1.2k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
WebSockets (confoo)
Igor Wiedler
March 02, 2012
More Decks by Igor Wiedler
See All by Igor Wiedler
Redis Bedtime Stories
igorw
1
390
Wide Event Analytics (LISA19)
igorw
4
960
a day in the life of a request
igorw
0
180
production: an owner's manual
igorw
0
210
The Power of 2
igorw
0
360
LISP 1.5 Programmer's Manual: A Dramatic Reading
igorw
0
500
The Moral Character of Software
igorw
1
340
interdisciplinary computing (domcode)
igorw
0
330
miniKanren (clojure berlin)
igorw
1
350
Other Decks in Programming
See All in Programming
クラウドゲーミングのパフォーマンス最適化に挑む / Cloud Gaming Performance Tuning
vivion
0
280
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
120
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1k
AI時代のTerminal環境を UNIX哲学で設計・運用する
yasunori0418
1
270
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
2
200
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
180
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
110
Performance Optimization With LLMs
xleitix
0
210
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
1.3k
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
120
AI時代のIaC入門 〜なぜインフラをコードで管理したいのか?〜 / Introduction to IaC in the AI Era
akihisaikeda
5
810
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
7k
Featured
See All Featured
Google's AI Overviews - The New Search
badams
0
1.6k
Visualization
eitanlees
153
17k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Are puppies a ranking factor?
jonoalderson
2
4.1k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.5k
Producing Creativity
orderedlist
PRO
348
41k
The SEO Collaboration Effect
kristinabergwall1
1
600
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Why Our Code Smells
bkeepers
PRO
340
58k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
740
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
380
Transcript
WEBSOCKETS Friday, March 2, 12
• phpBB • Symfony2 • Silex • Composer igorw @igorwesome
Friday, March 2, 12
Friday, March 2, 12
Friday, March 2, 12
WEBSOCKETS Friday, March 2, 12
WEB Friday, March 2, 12
Application HTTP Presentation TCP Session TCP Transport TCP Network IP
Data Link Physical Friday, March 2, 12
Application HTTP Presentation TCP Session TCP Transport TCP Network IP
Data Link Physical Friday, March 2, 12
HTTP Friday, March 2, 12
client Friday, March 2, 12
request client Friday, March 2, 12
reponse client request Friday, March 2, 12
THIS IS A GOOD THING Friday, March 2, 12
BUT Friday, March 2, 12
NOT FOR EVERYTHING Friday, March 2, 12
UNIDIRECTIONAL Friday, March 2, 12
Friday, March 2, 12
LATENCY Friday, March 2, 12
STATELESS Friday, March 2, 12
Application HTTP Presentation TCP Session TCP Transport TCP Network IP
Data Link Physical Friday, March 2, 12
Application HTTP Presentation TCP Session TCP Transport TCP Network IP
Data Link Physical Friday, March 2, 12
WEBSOCKETS Friday, March 2, 12
SOCKETS Friday, March 2, 12
WEBSOCKETS Friday, March 2, 12
PROTOCOL API Friday, March 2, 12
THE WEBSOCKET PROTOCOL Friday, March 2, 12
browser Friday, March 2, 12
Friday, March 2, 12
Friday, March 2, 12
Friday, March 2, 12
• Handshake / Upgrade • TCP • Proxies • Supports
TLS (SSL) Friday, March 2, 12
Friday, March 2, 12
RFC 6455 Friday, March 2, 12
COMET Friday, March 2, 12
THE WEBSOCKET API Friday, March 2, 12
browser Friday, March 2, 12
Friday, March 2, 12
var ws = new WebSocket('ws://example.org:8080/updates'); ws.onopen = function () {
ws.send('hello'); }; ws.onmessage = function (message) { console.log(message.data); }; Friday, March 2, 12
JS INTERFACE • WebSocket • onopen • onmessage • onerror
• onclose • binaryType • MessageEvent • data Friday, March 2, 12
browser API PROTOCOL Friday, March 2, 12
Friday, March 2, 12
• built on node.js • abstracts socket communication • supports
fallback transports Friday, March 2, 12
• session storage • namespacing • acknowledgement • broadcasting •
reconnection Friday, March 2, 12
• json serialization • heartbeats • connection ids • io.sockets
collection Friday, March 2, 12
4.0+ (2009) 6.0+ (2011) 10.70+ (2012) 5.0+ (2010) 10+ (2012)
BROWSER SUPPORT Friday, March 2, 12
4.0+ 3.0+ 10.61+ 3.0+ 5.5+ WITH SOCKET.IO Friday, March 2,
12
Friday, March 2, 12
Y U NO PHP? Friday, March 2, 12
Friday, March 2, 12
Friday, March 2, 12
$context = new ZMQContext(); $sock = $context->getSocket(ZMQ::SOCKET_PUB); $sock->connect('tcp://127.0.0.1:5555'); $msg =
json_encode([ 'type' => 'debug', 'data' => ['foo', 'bar', 'baz'] ]); $sock->send($msg); Friday, March 2, 12
$context = new ZMQContext(); $sock = $context->getSocket(ZMQ::SOCKET_PUB); $sock->connect('tcp://127.0.0.1:5555'); $msg =
json_encode([ 'type' => 'debug', 'data' => ['foo', 'bar', 'baz'] ]); $sock->send($msg); Friday, March 2, 12
$context = new ZMQContext(); $sock = $context->getSocket(ZMQ::SOCKET_PUB); $sock->connect('tcp://127.0.0.1:5555'); $msg =
json_encode([ 'type' => 'debug', 'data' => ['foo', 'bar', 'baz'] ]); $sock->send($msg); Friday, March 2, 12
$context = new ZMQContext(); $sock = $context->getSocket(ZMQ::SOCKET_PUB); $sock->connect('tcp://127.0.0.1:5555'); $msg =
json_encode([ 'type' => 'debug', 'data' => ['foo', 'bar', 'baz'] ]); $sock->send($msg); Friday, March 2, 12
Friday, March 2, 12
var io = require('socket.io').listen(8080), zmq = require('zmq'), sock = zmq.socket('sub');
sock.subscribe(''); sock.bind('tcp://*:5555'); sock.on('message', function (msg) { var event = JSON.parse(msg); io.sockets.emit(event.type, event.data); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), zmq = require('zmq'), sock = zmq.socket('sub');
sock.subscribe(''); sock.bind('tcp://*:5555'); sock.on('message', function (msg) { var event = JSON.parse(msg); io.sockets.emit(event.type, event.data); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), zmq = require('zmq'), sock = zmq.socket('sub');
sock.subscribe(''); sock.bind('tcp://*:5555'); sock.on('message', function (msg) { var event = JSON.parse(msg); io.sockets.emit(event.type, event.data); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), zmq = require('zmq'), sock = zmq.socket('sub');
sock.subscribe(''); sock.bind('tcp://*:5555'); sock.on('message', function (msg) { var event = JSON.parse(msg); io.sockets.emit(event.type, event.data); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), zmq = require('zmq'), sock = zmq.socket('sub');
sock.subscribe(''); sock.bind('tcp://*:5555'); sock.on('message', function (msg) { var event = JSON.parse(msg); io.sockets.emit(event.type, event.data); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), zmq = require('zmq'), sock = zmq.socket('sub');
sock.subscribe(''); sock.bind('tcp://*:5555'); sock.on('message', function (msg) { var event = JSON.parse(msg); io.sockets.emit(event.type, event.data); }); Friday, March 2, 12
<script src="http://localhost:8080/socket.io/socket.io.js"> </script> <script> var socket = io.connect('http://localhost:8080'); socket.on('debug', function
(data) { console.log(data); }); </script> Friday, March 2, 12
LE CODE •blog comments •chat •canvas Friday, March 2, 12
LE CODE •blog comments •chat •canvas Friday, March 2, 12
class CommentController extends Controller { public function createAction(Post $post) {
$comment = new Comment(); $comment->setPost($post); $request = $this->getRequest(); $form = $this->createForm(new CommentType(), $comment); $form->bindRequest($request); if ($form->isValid()) { $em = $this->getDoctrine()->getEntityManager(); $em->persist($comment); $em->flush(); $renderedRow = $this->renderView( 'AcmeBlogBundle:Comment:row.html.twig', array('comment' => $comment) ); return new Response($renderedRow, 201); } return new Response('{}', 400, array('Content-Type' => 'application/json')); } } Friday, March 2, 12
class CommentController extends Controller { public function createAction(Post $post) {
$comment = new Comment(); $comment->setPost($post); $request = $this->getRequest(); $form = $this->createForm(new CommentType(), $comment); $form->bindRequest($request); if ($form->isValid()) { $em = $this->getDoctrine()->getEntityManager(); $em->persist($comment); $em->flush(); $renderedRow = $this->renderView( 'AcmeBlogBundle:Comment:row.html.twig', array('comment' => $comment) ); return new Response($renderedRow, 201); } return new Response('{}', 400, array('Content-Type' => 'application/json')); } } Friday, March 2, 12
Secret Sauce Friday, March 2, 12
private function publishCommentCreate(Comment $comment) { $context = new \ZMQContext(); $sock
= $context->getSocket(\ZMQ::SOCKET_PUB); $sock->connect('tcp://127.0.0.1:5555'); $renderedRow = $this->renderView( 'AcmeBlogBundle:Comment:row.html.twig', array('comment' => $comment) ); $postId = $comment->getPost()->getId(); $msg = json_encode(array( 'type' => "post.$postId.comment.create", 'data' => $renderedRow, )); $sock->send($msg); } Friday, March 2, 12
private function publishCommentCreate(Comment $comment) { $context = new \ZMQContext(); $sock
= $context->getSocket(\ZMQ::SOCKET_PUB); $sock->connect('tcp://127.0.0.1:5555'); $renderedRow = $this->renderView( 'AcmeBlogBundle:Comment:row.html.twig', array('comment' => $comment) ); $postId = $comment->getPost()->getId(); $msg = json_encode(array( 'type' => "post.$postId.comment.create", 'data' => $renderedRow, )); $sock->send($msg); } Friday, March 2, 12
private function publishCommentCreate(Comment $comment) { $context = new \ZMQContext(); $sock
= $context->getSocket(\ZMQ::SOCKET_PUB); $sock->connect('tcp://127.0.0.1:5555'); $renderedRow = $this->renderView( 'AcmeBlogBundle:Comment:row.html.twig', array('comment' => $comment) ); $postId = $comment->getPost()->getId(); $msg = json_encode(array( 'type' => "post.$postId.comment.create", 'data' => $renderedRow, )); $sock->send($msg); } Friday, March 2, 12
$this->publishCommentCreate($comment); Friday, March 2, 12
var socket = io.connect('http://localhost:8080'); socket.on('post.'+postId+'.comment.create', function (data) { renderComment(data); });
Friday, March 2, 12
LE CODE •blog comments •chat •canvas Friday, March 2, 12
<div class="messages"></div> <form> <input type="text" name="message"> <button type="submit">Send</button> </form> <script
src="http://localhost:8080/socket.io/socket.io.js"></script> <script src="jquery-1.7.min.js"></script> <script src="chat.js"></script> Friday, March 2, 12
var socket = io.connect('http://localhost:8080'), messages = $('.messages'); socket.on('message', function (message)
{ var messageHtml = $('<div></div>').text(message.body); messages.append(messageHtml); messages.prop('scrollTop', 100000); }); Friday, March 2, 12
var socket = io.connect('http://localhost:8080'), messages = $('.messages'); socket.on('message', function (message)
{ var messageHtml = $('<div></div>').text(message.body); messages.append(messageHtml); messages.prop('scrollTop', 100000); }); Friday, March 2, 12
var form = $('form'); form.submit(function (event) { event.preventDefault(); var input
= form.find('*[name=message]'), body = input.val(); if (!body.length) { return; } socket.emit('message', { name: name, body: body }); input.val(''); }); Friday, March 2, 12
var form = $('form'); form.submit(function (event) { event.preventDefault(); var input
= form.find('*[name=message]'), body = input.val(); if (!body.length) { return; } socket.emit('message', { name: name, body: body }); input.val(''); }); Friday, March 2, 12
var io = require('socket.io').listen(8080); io.sockets.on('connection', function (socket) { socket.on('message', function
(message) { io.sockets.emit('message', message); }); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), messages; messages = []; io.sockets.on('connection', function
(socket) { messages.forEach(function (message) { socket.emit('message', message); }); socket.on('message', function (message) { io.sockets.emit('message', message); messages.push(message); }); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), messages; messages = []; io.sockets.on('connection', function
(socket) { messages.forEach(function (message) { socket.emit('message', message); }); socket.on('message', function (message) { io.sockets.emit('message', message); messages.push(message); }); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), bufferLimit = 15, messages; messages =
[]; io.sockets.on('connection', function (socket) { messages.forEach(function (message) { socket.emit('message', message); }); socket.on('message', function (message) { io.sockets.emit('message', message); messages.push(message); if (messages.length > bufferLimit) { messages = messages.splice(-bufferLimit, bufferLimit); } }); }); Friday, March 2, 12
var io = require('socket.io').listen(8080), bufferLimit = 15, messages; messages =
[]; io.sockets.on('connection', function (socket) { messages.forEach(function (message) { socket.emit('message', message); }); socket.on('message', function (message) { io.sockets.emit('message', message); messages.push(message); if (messages.length > bufferLimit) { messages = messages.splice(-bufferLimit, bufferLimit); } }); }); Friday, March 2, 12
LE CODE •blog comments •chat •canvas Friday, March 2, 12
USE CASES •Games •Notifications •Collaboration •Statistics •Chat Friday, March 2,
12
PUB/SUB Friday, March 2, 12
Push only? Friday, March 2, 12
EventSource. Friday, March 2, 12
LINKS • tools.ietf.org/html/rfc6455 • dev.w3.org/html5/websockets • developer.mozilla.org/en/WebSockets • socket.io •
github.com/igorw/websockets-talk Friday, March 2, 12
github.com/igorw/websockets-talk Friday, March 2, 12
CREDITS • thenounproject.com • stopwatch • lightning • sync •
refresh Friday, March 2, 12
Questions? @igorwesome speakerdeck.com /u/igorw joind.in/5997 Frögli? Friday, March 2, 12