SlideShare a Scribd company logo
WebSockets in Ruby
(and things you can do with them)
Ismael Celis @ismasan github.com/ismasan
new bamboo
new-bamboo.co.uk pusherapp.com
Polling
Long-polling
Web socket
websockets.org/about.html
HTML5 Web sockets
Use cases
•Chat (lame)
•Stocks (lame but challenging)
•Games
•Presence
•Collaboration
•Real-time notifications
WebSockets DOM API
<script type="text/javascript" charset="utf-8">
// Socket object
var socket = new WebSocket('ws://some.host.com');
// Callbacks
socket.onopen = function (evt) {
alert('Socket connected: ' + evt.data)
};
// Incoming server message
socket.onmessage = function (evt) {
alert( evt.data )
};
socket.onclose = function (evt) {
alert('Connection terminated')
// reconnect, etc.
};
</script>
WebSockets handshake
Request
Response
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com
^n:ds[4U
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Location: ws://example.com/demo
Sec-WebSocket-Protocol: sample
8jKS'y:G*Co,Wxa-
(draft 76)
"x00Hello Worldxff"
Messages
// Incoming server message
socket.onmessage = function (evt) {
alert( evt.data )
};
// Send message to server
socket.send("Hello server, this is a new client");
(Ruby) WebSockets server
•Speak WebSockets (handshake)
•Keep connections alive
•Performant!
•Scalable
•Threads? Evented?
EventMachine rubyeventmachine.com
require 'eventmachine'
module EchoServer
def receive_data(data)
send_data data
end
end
EventMachine::run {
EventMachine::start_server 'localhost', 8080, EchoServer
puts 'running echo server on 8080'
}
EM-WebSocket
github.com/igrigorik/em-websocket
EventMachine.run {
EventMachine::WebSocket.start(:host=>'0.0.0.0',:port=>8080) do |socket|
socket.onopen {
# publish message to the client
socket.send 'Websocket connection open'
}
socket.onmessage {|msg|
# echo message to client
socket.send "Received message: #{msg}"
}
end
}
Multicast - subscribers
...
@channel = Channel.new
...
socket.onopen {
@channel.subscribe socket
}
socket.onmessage { |msg|
@channel.send_message msg
}
socket.onclose {
@channel.unsubscribe socket
}
Multicast - subscribers
# Server
socket.onopen {
@channel.subscribe socket
}
class Channel
def initialize
@sockets = []
end
def subscribe( socket )
@sockets << socket
end
...
end
Multicast - channel
class Channel
...
def subscribe( socket )
@sockets << socket
end
def send_message( msg )
@sockets.each do |socket|
socket.send msg
end
end
def unsubscribe( socket )
@sockets.delete socket
end
end
Multicast - example
var socket = new WebSocket('ws://localhost:8080');
socket.onmessage = function( evt ) {
$('<li>')
.text(evt.data)
.appendTo('#messages');
}
<ul id="messages">
</ul>
HTML
Javascript
Multicast - example
github.com/ismasan/websockets_examples
Pick your protocol
STOMP CONNECT
login: <username>
passcode: <passcode>
<message
from=”john@server.com/ruby”
to=”jane@server.com/ruby”>
<body>Hey Jane!</body>
</message>
XMPP
Your own (JSON?)
Custom message format
JSON
Custom JSON format
{
“event”: “user_connected”,
{
“name” : “Ismael”,
“total_users” : 10
}
}
Event name
Custom data
“data”:
Custom JSON format
{
“event”: “user_message”,
{
“message” : “Hello!”,
“date” : “23 2010 21:12:28”
}
}
“data”:
Javascript wrapper
var socket = new FancyWebSocket('ws://localhost:8080');
...
socket.bind( 'user_connected', function (user_data) {
// Add user to screen
$('#connected_users').append('<li>' + user_data.name + '</li>');
});
socket.bind( 'user_message', function (msg_data) {
// Add message to screen
$('#messages').append('<li>' + msg_data.message + '</li>');
});
// Broadcast message - jQuery example
$('form#user_input').submit(function () {
var msg = $(this).find('input[name=message]').val();
socket.send( 'user_message', {name: 'Ismael', message: msg} );
return false;
});
Javascript wrapper
{
“event” : “user_message”,
{
“name” : “Ismael”,
“message” : “hello!”
}
}
“data” :
Implementation gist.github.com/299789
var FancyWebSocket = function(url){
var conn = new WebSocket(url);
var callbacks = {};
this.bind = function(event_name, callback){
callbacks[event_name] = callbacks[event_name] || [];
callbacks[event_name].push(callback);
};
this.send = function(event_name, event_data){
var payload = JSON.stringify({event:event_name, data: event_data});
conn.send( payload );
};
// dispatch to the right handlers
conn.onmessage = function(evt){
var json = JSON.parse(evt.data)
dispatch(json.event, json.data)
};
conn.onclose = function(){dispatch('close',null)}
conn.onopen = function(){dispatch('open',null)}
var dispatch = function(event_name, message){
var chain = callbacks[event_name];
if(typeof chain == 'undefined') return; // no callbacks for this event
for(var i = 0; i < chain.length; i++){
chain[i]( message )
}
}
};
Implementation gist.github.com/299789
var FancyWebSocket = function(url){
var conn = new WebSocket(url);
var callbacks = {};
this.bind = function(event_name, callback){
callbacks[event_name] = callbacks[event_name] || [];
callbacks[event_name].push(callback);
};
this.send = function(event_name, event_data){
var payload = JSON.stringify({event:event_name, data:
event_data});
conn.send( payload );
};
Ismael Celis
Implementation gist.github.com/299789
var FancyWebSocket = function(url){
var conn = new WebSocket(url);
var callbacks = {};
this.bind = function(event_name, callback){
callbacks[event_name] = callbacks[event_name] || [];
callbacks[event_name].push(callback);
};
this.send = function(event_name, event_data){
var payload = JSON.stringify({event:event_name, data: event_d
conn.send( payload );
};
// dispatch to the right handlers
conn.onmessage = function(evt){
var json = JSON.parse(evt.data)
// dispatch to the right handlers
conn.onmessage = function(evt){
var json = JSON.parse(evt.data)
dispatch(json.event, json.data)
};
conn.onclose = function(){dispatch('close',null)}
conn.onopen = function(){dispatch('open',null)}
var dispatch = function(event_name, message){
var chain = callbacks[event_name];
if(typeof chain == 'undefined') return; // no callbacks
for this event
for(var i = 0; i < chain.length; i++){
chain[i]( message )
}
Implementation
WebSocket
gist.github.com/299789
var FancyWebSocket = function(url){
// dispatch to the right handlers
conn.onmessage = function(evt){
var json = JSON.parse(evt.data)
dispatch(json.event, json.data)
};
conn.onclose = function(){dispatch('close',null)}
conn.onopen = function(){dispatch('open',null)}
var dispatch = function(event_name, message){
var chain = callbacks[event_name];
// no callbacks for this event
if(typeof chain == 'undefined') return;
for(var i = 0; i < chain.length; i++){
chain[i]( message )
}
}
};
Implementation gist.github.com/299789
socket.send( 'user_message', {name: 'Ismael', message: msg} );
Implementation gist.github.com/299789
this.send = function(event_name, event_data){
var payload = JSON.stringify({event:event_name, data: event_data});
conn.send( payload ); // <= send JSON data to socket server
return this;
};
Multicast - JSON data
github.com/ismasan/websockets_examples
Multicast - JSON data
$('#canvas').mousedown(function () {
drawing = true;
})
.mouseup(function () {
drawing = false;
})
.mousemove(function (evt) {
if(drawing) {
var point = [evt.pageX, evt.pageY];
socket.send('mousemove', point);
}
});
Multicast - JSON data
var ctx = document.getElementById
('canvas').getContext('2d');
ctx.lineWidth = 1;
ctx.strokeStyle = '#ffffff';
ctx.beginPath();
ctx.moveTo(0, 0);
// Listen to other user's moves
socket.bind('mousemove', function (point) {
ctx.lineTo(point[0],point[1]);
ctx.stroke();
});
Activity dashboard
Rails Rumble dashboard
Scaling
?
pusherapp.com
pusherapp.com
Your app
REST
Browsers
Websockets
Existing HTTP
pusherapp.com
pusherapp.com
<script src="http://js.pusherapp.com/1.6/pusher.min.js"></script>
<script type="text/javascript" charset="utf-8">
var socket = new Pusher('293d8ae77496e1fc053b');
</script>
pusherapp.com
var socket = new Pusher('293d8ae77496e1fc053b');
// Subscribe to channels
var channel = socket.subscribe( 'test' );
channel.bind( 'new_message', function (data) {
alert( data.message );
})
pusherapp.com
// Subscribe to PRESENCE channel
var chat = socket.subscribe( 'presence-chat' );
// Listen to new members
chat.bind( 'pusher:member_added', function (member) {
alert( member.user_data.name );
})
require 'pusher'
require 'sinatra'
post '/messages' do
message = Message.create(params[:message])
Pusher['presence-chat'].trigger(:new_message, message.attributes)
redirect '/messages'
end
pusherapp.com
$ gem install pusher
pusherapp.com
github.com/
lifo/cramp
ismasan/websockets_examples
newbamboo/rumbledash
blog.new-bamboo.co.uk
blog.pusherapp.com

More Related Content

PDF
神に近づくx/net/context (Finding God with x/net/context)
PDF
Web Crawling with NodeJS
PPTX
The Promised Land (in Angular)
PDF
Asynchronous PHP and Real-time Messaging
KEY
HTML5 Web Messaging
PDF
"The little big project. From zero to hero in two weeks with 3 front-end engi...
PDF
WebSockets, Unity3D, and Clojure
PDF
A Gentle Introduction to Event Loops
神に近づくx/net/context (Finding God with x/net/context)
Web Crawling with NodeJS
The Promised Land (in Angular)
Asynchronous PHP and Real-time Messaging
HTML5 Web Messaging
"The little big project. From zero to hero in two weeks with 3 front-end engi...
WebSockets, Unity3D, and Clojure
A Gentle Introduction to Event Loops

What's hot (20)

PPTX
ES6 is Nigh
PPTX
Async Frontiers
PDF
FwDays 2021: Metarhia Technology Stack for Node.js
PDF
Asynchronous programming done right - Node.js
PPTX
JavaScript on the Desktop
ODP
The promise of asynchronous PHP
PDF
Future Decoded - Node.js per sviluppatori .NET
PPTX
Avoiding callback hell in Node js using promises
PDF
The Open Web and what it means
PDF
Clojure@Nuday
PDF
Unity and WebSockets
ODP
The promise of asynchronous php
PDF
Asynchronous Programming FTW! 2 (with AnyEvent)
PDF
HTML5 & The Open Web - at Nackademin
PDF
Callbacks, promises, generators - asynchronous javascript
PPTX
Bare-knuckle web development
PDF
Node.js in action
PDF
"Auth for React.js APP", Nikita Galkin
PDF
React PHP: the NodeJS challenger
PDF
JavaScript APIs - The Web is the Platform - MDN Hack Day, Santiago, Chile
ES6 is Nigh
Async Frontiers
FwDays 2021: Metarhia Technology Stack for Node.js
Asynchronous programming done right - Node.js
JavaScript on the Desktop
The promise of asynchronous PHP
Future Decoded - Node.js per sviluppatori .NET
Avoiding callback hell in Node js using promises
The Open Web and what it means
Clojure@Nuday
Unity and WebSockets
The promise of asynchronous php
Asynchronous Programming FTW! 2 (with AnyEvent)
HTML5 & The Open Web - at Nackademin
Callbacks, promises, generators - asynchronous javascript
Bare-knuckle web development
Node.js in action
"Auth for React.js APP", Nikita Galkin
React PHP: the NodeJS challenger
JavaScript APIs - The Web is the Platform - MDN Hack Day, Santiago, Chile
Ad

Similar to Websockets talk at Rubyconf Uruguay 2010 (20)

PDF
Websockets, Ruby y Pusher Webprendedor 2010
PPTX
Html5 websockets
PDF
WebSocket Push Fallback - Transcript.pdf
PDF
Bartosz Zaczyński (Grand Parade Poland) - WebSocket for Dummies
PDF
Websockets en Ruby en 5 Minutos
PDF
Real-Time with Flowdock
PPTX
presentation in .net programming web sockets.pptx
PPTX
Web sockets Introduction
ODP
Building Websocket Applications with GlassFish and Grizzly
ZIP
Websocket protocol overview
PPTX
WebSockets-Revolutionizing-Real-Time-Communication.pptx
PPTX
Enhancing Mobile User Experience with WebSocket
PPTX
Intro to WebSockets
PPS
jWebSocket MobileTechCon 2010 - WebSockets on Android, Symbian and BlackBerry
PPS
Jwebsocketmobiletechcon2010en 100912071225 Phpapp01
PDF
WebSocket
PPTX
WebSockets in JEE 7
ODP
SockJS Intro
PPTX
HTML 5 - Web Sockets
PPTX
Websockets, Ruby y Pusher Webprendedor 2010
Html5 websockets
WebSocket Push Fallback - Transcript.pdf
Bartosz Zaczyński (Grand Parade Poland) - WebSocket for Dummies
Websockets en Ruby en 5 Minutos
Real-Time with Flowdock
presentation in .net programming web sockets.pptx
Web sockets Introduction
Building Websocket Applications with GlassFish and Grizzly
Websocket protocol overview
WebSockets-Revolutionizing-Real-Time-Communication.pptx
Enhancing Mobile User Experience with WebSocket
Intro to WebSockets
jWebSocket MobileTechCon 2010 - WebSockets on Android, Symbian and BlackBerry
Jwebsocketmobiletechcon2010en 100912071225 Phpapp01
WebSocket
WebSockets in JEE 7
SockJS Intro
HTML 5 - Web Sockets
Ad

Recently uploaded (20)

PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Approach and Philosophy of On baking technology
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
cuic standard and advanced reporting.pdf
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
MYSQL Presentation for SQL database connectivity
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Spectroscopy.pptx food analysis technology
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPT
Teaching material agriculture food technology
PPTX
Cloud computing and distributed systems.
PDF
Encapsulation theory and applications.pdf
PPTX
Big Data Technologies - Introduction.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Unlocking AI with Model Context Protocol (MCP)
Advanced methodologies resolving dimensionality complications for autism neur...
Approach and Philosophy of On baking technology
Building Integrated photovoltaic BIPV_UPV.pdf
The AUB Centre for AI in Media Proposal.docx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Encapsulation_ Review paper, used for researhc scholars
cuic standard and advanced reporting.pdf
Reach Out and Touch Someone: Haptics and Empathic Computing
Dropbox Q2 2025 Financial Results & Investor Presentation
MYSQL Presentation for SQL database connectivity
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Spectroscopy.pptx food analysis technology
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Teaching material agriculture food technology
Cloud computing and distributed systems.
Encapsulation theory and applications.pdf
Big Data Technologies - Introduction.pptx

Websockets talk at Rubyconf Uruguay 2010

  • 1. WebSockets in Ruby (and things you can do with them) Ismael Celis @ismasan github.com/ismasan new bamboo new-bamboo.co.uk pusherapp.com
  • 3. Use cases •Chat (lame) •Stocks (lame but challenging) •Games •Presence •Collaboration •Real-time notifications
  • 4. WebSockets DOM API <script type="text/javascript" charset="utf-8"> // Socket object var socket = new WebSocket('ws://some.host.com'); // Callbacks socket.onopen = function (evt) { alert('Socket connected: ' + evt.data) }; // Incoming server message socket.onmessage = function (evt) { alert( evt.data ) }; socket.onclose = function (evt) { alert('Connection terminated') // reconnect, etc. }; </script>
  • 5. WebSockets handshake Request Response GET /demo HTTP/1.1 Host: example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa- (draft 76)
  • 6. "x00Hello Worldxff" Messages // Incoming server message socket.onmessage = function (evt) { alert( evt.data ) }; // Send message to server socket.send("Hello server, this is a new client");
  • 7. (Ruby) WebSockets server •Speak WebSockets (handshake) •Keep connections alive •Performant! •Scalable •Threads? Evented?
  • 8. EventMachine rubyeventmachine.com require 'eventmachine' module EchoServer def receive_data(data) send_data data end end EventMachine::run { EventMachine::start_server 'localhost', 8080, EchoServer puts 'running echo server on 8080' }
  • 9. EM-WebSocket github.com/igrigorik/em-websocket EventMachine.run { EventMachine::WebSocket.start(:host=>'0.0.0.0',:port=>8080) do |socket| socket.onopen { # publish message to the client socket.send 'Websocket connection open' } socket.onmessage {|msg| # echo message to client socket.send "Received message: #{msg}" } end }
  • 10. Multicast - subscribers ... @channel = Channel.new ... socket.onopen { @channel.subscribe socket } socket.onmessage { |msg| @channel.send_message msg } socket.onclose { @channel.unsubscribe socket }
  • 11. Multicast - subscribers # Server socket.onopen { @channel.subscribe socket } class Channel def initialize @sockets = [] end def subscribe( socket ) @sockets << socket end ... end
  • 12. Multicast - channel class Channel ... def subscribe( socket ) @sockets << socket end def send_message( msg ) @sockets.each do |socket| socket.send msg end end def unsubscribe( socket ) @sockets.delete socket end end
  • 13. Multicast - example var socket = new WebSocket('ws://localhost:8080'); socket.onmessage = function( evt ) { $('<li>') .text(evt.data) .appendTo('#messages'); } <ul id="messages"> </ul> HTML Javascript
  • 15. Pick your protocol STOMP CONNECT login: <username> passcode: <passcode> <message from=”john@server.com/ruby” to=”jane@server.com/ruby”> <body>Hey Jane!</body> </message> XMPP Your own (JSON?)
  • 17. Custom JSON format { “event”: “user_connected”, { “name” : “Ismael”, “total_users” : 10 } } Event name Custom data “data”:
  • 18. Custom JSON format { “event”: “user_message”, { “message” : “Hello!”, “date” : “23 2010 21:12:28” } } “data”:
  • 19. Javascript wrapper var socket = new FancyWebSocket('ws://localhost:8080'); ... socket.bind( 'user_connected', function (user_data) { // Add user to screen $('#connected_users').append('<li>' + user_data.name + '</li>'); }); socket.bind( 'user_message', function (msg_data) { // Add message to screen $('#messages').append('<li>' + msg_data.message + '</li>'); });
  • 20. // Broadcast message - jQuery example $('form#user_input').submit(function () { var msg = $(this).find('input[name=message]').val(); socket.send( 'user_message', {name: 'Ismael', message: msg} ); return false; }); Javascript wrapper { “event” : “user_message”, { “name” : “Ismael”, “message” : “hello!” } } “data” :
  • 21. Implementation gist.github.com/299789 var FancyWebSocket = function(url){ var conn = new WebSocket(url); var callbacks = {}; this.bind = function(event_name, callback){ callbacks[event_name] = callbacks[event_name] || []; callbacks[event_name].push(callback); }; this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); }; // dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) }; conn.onclose = function(){dispatch('close',null)} conn.onopen = function(){dispatch('open',null)} var dispatch = function(event_name, message){ var chain = callbacks[event_name]; if(typeof chain == 'undefined') return; // no callbacks for this event for(var i = 0; i < chain.length; i++){ chain[i]( message ) } } };
  • 22. Implementation gist.github.com/299789 var FancyWebSocket = function(url){ var conn = new WebSocket(url); var callbacks = {}; this.bind = function(event_name, callback){ callbacks[event_name] = callbacks[event_name] || []; callbacks[event_name].push(callback); }; this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); };
  • 23. Ismael Celis Implementation gist.github.com/299789 var FancyWebSocket = function(url){ var conn = new WebSocket(url); var callbacks = {}; this.bind = function(event_name, callback){ callbacks[event_name] = callbacks[event_name] || []; callbacks[event_name].push(callback); }; this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_d conn.send( payload ); }; // dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data)
  • 24. // dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) }; conn.onclose = function(){dispatch('close',null)} conn.onopen = function(){dispatch('open',null)} var dispatch = function(event_name, message){ var chain = callbacks[event_name]; if(typeof chain == 'undefined') return; // no callbacks for this event for(var i = 0; i < chain.length; i++){ chain[i]( message ) } Implementation WebSocket gist.github.com/299789
  • 25. var FancyWebSocket = function(url){ // dispatch to the right handlers conn.onmessage = function(evt){ var json = JSON.parse(evt.data) dispatch(json.event, json.data) }; conn.onclose = function(){dispatch('close',null)} conn.onopen = function(){dispatch('open',null)} var dispatch = function(event_name, message){ var chain = callbacks[event_name]; // no callbacks for this event if(typeof chain == 'undefined') return; for(var i = 0; i < chain.length; i++){ chain[i]( message ) } } }; Implementation gist.github.com/299789
  • 26. socket.send( 'user_message', {name: 'Ismael', message: msg} ); Implementation gist.github.com/299789 this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); // <= send JSON data to socket server return this; };
  • 27. Multicast - JSON data github.com/ismasan/websockets_examples
  • 28. Multicast - JSON data $('#canvas').mousedown(function () { drawing = true; }) .mouseup(function () { drawing = false; }) .mousemove(function (evt) { if(drawing) { var point = [evt.pageX, evt.pageY]; socket.send('mousemove', point); } });
  • 29. Multicast - JSON data var ctx = document.getElementById ('canvas').getContext('2d'); ctx.lineWidth = 1; ctx.strokeStyle = '#ffffff'; ctx.beginPath(); ctx.moveTo(0, 0); // Listen to other user's moves socket.bind('mousemove', function (point) { ctx.lineTo(point[0],point[1]); ctx.stroke(); });
  • 37. pusherapp.com var socket = new Pusher('293d8ae77496e1fc053b'); // Subscribe to channels var channel = socket.subscribe( 'test' ); channel.bind( 'new_message', function (data) { alert( data.message ); })
  • 38. pusherapp.com // Subscribe to PRESENCE channel var chat = socket.subscribe( 'presence-chat' ); // Listen to new members chat.bind( 'pusher:member_added', function (member) { alert( member.user_data.name ); })
  • 39. require 'pusher' require 'sinatra' post '/messages' do message = Message.create(params[:message]) Pusher['presence-chat'].trigger(:new_message, message.attributes) redirect '/messages' end pusherapp.com $ gem install pusher