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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
エージェントを使い続けるためのメタワーク / Meta-work for keeping using the agent
rkaga
6
1.9k
自作Discord音声botをLambda MicroVMsに移行した話 / Migrating My Discord Voice Bot to Lambda MicroVMs
akihisaikeda
0
160
Seven New Principles of Software Engineering
yegor256
0
330
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
150
GraphQL の onError と Nullability のこれから
quramy
0
190
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
200
Modernizing iOS Apps
seyfoyun
0
120
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.8k
Kotlinの15年とServer-Side Kotlin
n_takehata
1
170
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
150
AmebaブログはKMPから卒業します
kmars0605
0
250
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
130
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
464
34k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
Done Done
chrislema
187
17k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Building AI with AI
inesmontani
PRO
1
1.3k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Optimizing for Happiness
mojombo
378
71k
A Modern Web Designer's Workflow
chriscoyier
699
190k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
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