SlideShare a Scribd company logo
WebSocket for Web
Rubyists
@ryudoawaru at OEDO’05
はじめに
発表する機会をいただき
ありがとうございます
提 供提 供
五倍紅寶石五倍紅寶石
自己紹介
鄧 慕凡(テン ムファン)
a.k.a: 竜堂 終
両方どもある小説の登場人物
Github / Twitter: @ryudoawaru
http://ryudo.tw
台湾人であり
ルビーストRubeastであり
Rubyの肩書
RubyConf Taiwan
執行委員長
Rails Girls Taipei
主催人
仕事は
五倍の紅宝石
http://5xruby.tw/en
無限虫制師
Unlimited Bug WorksGenerator
弊社の業務
Ruby / Rails の 教育業者
コンサルタンシー / オフショア
海外の取引先は日本、シンガポールなどを持ちます
Rubyの広める
RailsGirls / RubyConf…etc
RWC初めの海外スポンサーになりま
した
ここから、英語で話す
Agenda
Introduce WebSocket / EM-Websocket.
Architectural Perception for Web
Rubyists.
WebSocket
RFC 6455
Websocket
W3C / HTML5 Standard
Standard Javascript API
Full-duplex
Pub-Sub between client and server
Search in
rubygems.org
WebSocket For Web Rubyists
Gem Category
EventMachine-Websocket
Faye-Websokcet
EM-Websocket
EM-Websocket
From 2009
Simple implementation
Easily handle c10k by 1 process
http://shokai.org/blog/archives/7149
Typical Server Side Code
EventMachine::WebSocket.start(:host =>
"0.0.0.0", :port => 8080) do |ws|
ws.onopen { ws.send "Hello Client!"}
ws.onmessage { |msg| ws.send "Pong: #{msg}" }
ws.onclose { puts "WebSocket closed" }
end
Typical Client Side Code
var ws = new WebSocket('ws://host/uri');
ws.onopen = function() {
show('websocket opened');
};
ws.onclose = function() {
show('websocket closed');
}
ws.onmessage = function(m) {
show('websocket message: ' + m.data);
};
ws.send('Hello Websocket!!');
How does it work
Client Server
Handshake Response
Websocket
Handshake Request
GET /chat HTTP 1.1
Host: server.host.com
Upgrade: Websocket
Connection: Upgrade
Origin: http://host.com
Sec-Websocket-Key: “WwV7thr/Uwrg3mA57risrQ=="
Sec-WebSocket-Version:"13"
Connection:”Upgrade"
Sec-WebSocket-Accept: F0VaFFGV/
JHx1hJWBlhuJAqdse8=
Upgrade:"websocket"
Events
onopen:When new connection is
established
onmessage:When new message comes
from another side
onclose:When connection is closed by
the other side
Methods of Handshake Object
send:Send message to client or server
side.
close:Close connection.
Message Flow
Server
Client
Client
Client
1. send msg
2. onmessage
3. Send to
all clients
4. onmessage
Basic EM-WebSocket Code Style
conns_in_channel = Set.new
EM::WebSocket.start(...) do |ws|
ws.onopen do |request|
conns_in_channel.add ws
end
ws.onmessage do |msg|
conns_in_channel.each do |conn|
EM.next_tick{conn.send(msg)}
end
end
ws.onclose do
conns_in_channel.delete ws
end
end
Store connection
Remove connection on quit
Set to store connection
Send msg to connections 1 by 1
WebSocket Protocol
is Simple.
But it’s never easy to
make a great product.
Architectural Issue
Application Stack Style
Authentication
Application Stack
Style
Standalone or in App?
Two Styles
Standalone
In-App
Standalone
Web Service
Stack
WebSocket
Service
Stack
Normal HTTP Request
WS Request
In App Style
Web Service
Logic
Normal HTTP
Logic
Normal HTTP Request
WS Request
Live with HTTP Service in the
Rack Stack
request.websocket?
Rack Stack
WebSocketOther
Rack
Stuffs
YES NO
Identify by Request Headers
# middlewares/chat_backend.rb
def call(env)
if Faye::WebSocket.websocket?(env)
# WebSockets logic goes here
ws.rack_response
else
@app.call(env)
end
end
https://devcenter.heroku.com/articles/
ruby-websockets
Identify by Request Headers
# config/routes.rb
Example::Application.routes.draw do
match "/websocket", :to => ActionCable.server,
via: [:get, :post]
end
https://github.com/rails/actioncable
Standalone or In
App?
Normal Web Services
Keeps Connection
for very short
period.
Process could be
terminated w/o
affecting any
client.
Client Server
open
close
open
close
WebSocket Service
Long-running
Connection
Stop process
means killing all
connections.
Server
Client
Client
Client
Concurrency Model
WebSocket Gems use one of following
concurrency models:
Reactor: EventMachine based Gems.
Thread: Tubesock.
Mixed: ActionCable
This may conflicts with model of your
normal Web Services.
Comparison of Connection
Features
Normal Web Works WebSocket
Connection Period short long
Concurrency Model
Depend on App
Server
Reactor or Thread
Process Long-
Running?
No Yes
Authenticate
Confirm identity in handshake
Authentication Issue
Client Server
Handshake Request
Handshake Response
Websocket
Confirm at this point!
Possible Methods to Confirm
Identity
Cookie
Headers
URL / Query Parameters
Identify by Cookie
Easy approach for web developers.
WebSocket may run at different host.
Some browsers don’t support cookie on
ws:// request.
Most mobile APP’s http client may not
support cookie/session by default.
Identify by Request Headers
Unable to add custom header in the
JavaScript WebSockets API.
Identify by URL
Client
GET http://host/chat
WebSocketWeb Service
Use ticket to handshake
Identity
confirmed
Generate URL: ws://host2/abc1234 as
“ticket”
Attention
Security issue:
The “ticket" should be removed from
database after connection established.
Should only be valid in a short time.
Showcase
Chatroom for Forum
iOS APPWEB
http://www.focus-sport.club.tw/
Serve all platforms by one stack.
Runs Permanently.
Handle more than 1k concurrent
connections very easily.
ご清聴ありがとうございました
Any Question?

More Related Content

WebSocket For Web Rubyists