Module: Sinatra::WebSocketIO
- Defined in:
- lib/sinatra/websocketio/client.rb,
lib/sinatra-websocketio/helpers.rb,
lib/sinatra-websocketio/options.rb,
lib/sinatra-websocketio/version.rb,
lib/sinatra/websocketio_nostart.rb,
lib/sinatra-websocketio/javascript.rb,
lib/sinatra-websocketio/application.rb,
lib/sinatra-websocketio/websocketio.rb
Defined Under Namespace
Modules: Helpers
Classes: Client
Constant Summary
collapse
- VERSION =
"0.4.1"
- @@running =
false
Class Method Summary
collapse
Instance Method Summary
collapse
Class Method Details
.create_session(ip_addr) ⇒ Object
76
77
78
|
# File 'lib/sinatra-websocketio/websocketio.rb', line 76
def self.create_session(ip_addr)
Digest::MD5.hexdigest "#{Time.now.to_i}_#{Time.now.usec}_#{ip_addr}"
end
|
.default_options ⇒ Object
12
13
14
15
16
|
# File 'lib/sinatra-websocketio/options.rb', line 12
def self.default_options
{
:port => [(ENV['WS_PORT']||9000).to_i, lambda{|v| v.kind_of? Fixnum and v > 0 }]
}
end
|
.javascript(*js_file_names) ⇒ Object
4
5
6
7
8
9
10
11
12
13
|
# File 'lib/sinatra-websocketio/javascript.rb', line 4
def self.javascript(*js_file_names)
js_file_names = ['websocketio.js', 'event_emitter.js'] if js_file_names.empty?
js = ''
js_file_names.each do |i|
File.open(File.expand_path "../js/#{i}", File.dirname(__FILE__)) do |f|
js += f.read
end
end
js
end
|
.options ⇒ Object
18
19
20
21
22
23
24
25
26
|
# File 'lib/sinatra-websocketio/options.rb', line 18
def self.options
@@options ||= (
opts = {}
default_options.each do |k,v|
opts[k] = v[0]
end
opts
)
end
|
.options=(opts) ⇒ Object
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/sinatra-websocketio/options.rb', line 28
def self.options=(opts)
@@options = {}
opts.each do |k,v|
k = k.to_sym
unless default_options.include? k
STDERR.puts "!! Sinatra::WebSocketIO setting - \"#{k}\" is not valid key"
else
unless default_options[k][1].call(v)
default = default_options[k][0]
STDERR.puts "!! Sinatra::WebSocketIO setting - \"#{k} => #{v}\" is not valid. set default \"#{k} => #{default}\""
@@options[k] = default
else
@@options[k] = v
end
end
end
default_options.each do |k, v|
@@options[k] = v[0] unless @@options.include? k
end
@@options
end
|
.parse_handshake_params(path) ⇒ Object
80
81
82
83
84
85
86
87
|
# File 'lib/sinatra-websocketio/websocketio.rb', line 80
def self.parse_handshake_params(path)
tmp = path.gsub(/^\//,'').split(/\=+/)
params = {}
while !tmp.empty?
params[tmp.shift.to_sym] = tmp.shift
end
params
end
|
.push(type, data, opt = {}) ⇒ Object
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# File 'lib/sinatra-websocketio/websocketio.rb', line 56
def self.push(type, data, opt={})
if opt.include? :to
return unless self.sessions.include? opt[:to]
s = self.sessions[opt[:to]][:websocket]
begin
s.send({:type => type, :data => data}.to_json)
rescue => e
emit :error, "websocketio push error (session:#{opt[:to]})"
end
else
self.sessions.keys.each do |id|
push type, data, :to => id
end
end
end
|
.registered(app) ⇒ Object
4
5
6
7
8
9
10
11
|
# File 'lib/sinatra-websocketio/application.rb', line 4
def self.registered(app)
app.helpers Sinatra::WebSocketIO::Helpers
app.get '/websocketio/websocketio.js' do
content_type 'application/javascript'
@js ||= ERB.new(Sinatra::WebSocketIO.javascript).result(binding)
end
end
|
.running? ⇒ Boolean
5
6
7
|
# File 'lib/sinatra-websocketio/websocketio.rb', line 5
def self.running?
@@running
end
|
.sessions ⇒ Object
72
73
74
|
# File 'lib/sinatra-websocketio/websocketio.rb', line 72
def self.sessions
@@sessions ||= Hash.new
end
|
.start ⇒ Object
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/sinatra-websocketio/websocketio.rb', line 9
def self.start
return if running?
@@running = true
EM::defer do
while !EM::reactor_running? do
sleep 1
end
puts "Sinatra::WebSocketIO.start port:#{options[:port]}"
EM::WebSocket.run :host => "0.0.0.0", :port => options[:port] do |ws|
ws.onopen do |handshake|
params = parse_handshake_params handshake.path
remote_addr = Socket.unpack_sockaddr_in(ws.get_peername)[1]
session_id = params[:session] || create_session(remote_addr)
if self.sessions.include? session_id
ws.send({:type => :error, :data => "invalid session_id (#{session_id})"}.to_json)
ws.close
else
self.sessions[session_id] = {
:websocket => ws,
:remote_addr => remote_addr
}
ws.onclose do
self.sessions.delete session_id
self.emit :disconnect, session_id
end
ws.onmessage do |msg|
begin
data = ::JSON.parse msg
rescue => e
self.emit :error, e
end
self.emit data['type'], data['data'], session_id if data
end
ws.send({:type => :__session_id, :data => session_id}.to_json)
self.emit :connect, session_id
end
end
end
EM::add_periodic_timer 300 do
push :__heartbeat, {:time => Time.now}
end
end
end
|
Instance Method Details
#websocketio ⇒ Object
8
9
10
|
# File 'lib/sinatra-websocketio/options.rb', line 8
def websocketio
WebSocketIO.options
end
|
#websocketio=(options) ⇒ Object
4
5
6
|
# File 'lib/sinatra-websocketio/options.rb', line 4
def websocketio=(options)
WebSocketIO.options = options
end
|