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

What's hot

ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
Domenic Denicola
 
Async Frontiers
Async FrontiersAsync Frontiers
Async Frontiers
Domenic Denicola
 
FwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.jsFwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.js
Timur Shemsedinov
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
Piotr Pelczar
 
JavaScript on the Desktop
JavaScript on the DesktopJavaScript on the Desktop
JavaScript on the Desktop
Domenic Denicola
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
Wim Godden
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
Gianluca Carucci
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
Ankit Agarwal
 
The Open Web and what it means
The Open Web and what it meansThe Open Web and what it means
The Open Web and what it meansRobert Nyman
 
Unity and WebSockets
Unity and WebSocketsUnity and WebSockets
Unity and WebSocketsJosh Glover
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
Wim Godden
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)
xSawyer
 
HTML5 & The Open Web - at Nackademin
HTML5 & The Open Web -  at NackademinHTML5 & The Open Web -  at Nackademin
HTML5 & The Open Web - at NackademinRobert Nyman
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
Łukasz Kużyński
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
Johannes Brodwall
 
Node.js in action
Node.js in actionNode.js in action
Node.js in action
Simon Su
 
"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin
Fwdays
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challenger
vanphp
 
JavaScript APIs - The Web is the Platform - MDN Hack Day, Santiago, Chile
JavaScript APIs - The Web is the Platform - MDN Hack Day, Santiago, ChileJavaScript APIs - The Web is the Platform - MDN Hack Day, Santiago, Chile
JavaScript APIs - The Web is the Platform - MDN Hack Day, Santiago, ChileRobert Nyman
 

What's hot (20)

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

Similar to Websockets talk at Rubyconf Uruguay 2010

Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010Ismael Celis
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Server Side Events
Server Side EventsServer Side Events
Server Side Events
thepilif
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
Wim Godden
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
Peter Friese
 
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
WSO2
 
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
DevClub_lv
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to Nodejs
Gabriele Lana
 
Serverless Ballerina
Serverless BallerinaServerless Ballerina
Serverless Ballerina
Ballerina
 
From Node to Go
From Node to GoFrom Node to Go
From Node to Go
John Maxwell
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todaygerbille
 
NodeJS
NodeJSNodeJS
NodeJS
Alok Guha
 
HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranRobert Nyman
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
soft-shake.ch
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsSpeed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSockets
Yakov Fain
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
Paweł Kowalczuk
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloJavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloRobert Nyman
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
Yiguang Hu
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
Constantin Titarenko
 

Similar to Websockets talk at Rubyconf Uruguay 2010 (20)

Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010Websockets, Ruby y Pusher Webprendedor 2010
Websockets, Ruby y Pusher Webprendedor 2010
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Server Side Events
Server Side EventsServer Side Events
Server Side Events
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
 
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
 
Introduction to Nodejs
Introduction to NodejsIntroduction to Nodejs
Introduction to Nodejs
 
Serverless Ballerina
Serverless BallerinaServerless Ballerina
Serverless Ballerina
 
From Node to Go
From Node to GoFrom Node to Go
From Node to Go
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
 
NodeJS
NodeJSNodeJS
NodeJS
 
HTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - AltranHTML5 APIs - Where no man has gone before! - Altran
HTML5 APIs - Where no man has gone before! - Altran
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsSpeed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSockets
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao PauloJavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
JavaScript APIs - The Web is the Platform - MDN Hack Day, Sao Paulo
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
 
jQuery: Events, Animation, Ajax
jQuery: Events, Animation, AjaxjQuery: Events, Animation, Ajax
jQuery: Events, Animation, Ajax
 

Recently uploaded

Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 

Recently uploaded (20)

Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 

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(); });
  • 36. 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>
  • 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