sinatra-cometio 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -1
- data/README.md +14 -0
- data/lib/js/cometio.js +10 -1
- data/lib/sinatra-cometio/application.rb +71 -0
- data/lib/sinatra-cometio/options.rb +35 -0
- data/lib/sinatra-cometio/version.rb +4 -2
- data/lib/sinatra/cometio.rb +5 -3
- data/lib/sinatra/cometio/client.rb +9 -1
- data/sample/config.ru +1 -0
- data/sample/main.rb +1 -0
- data/sample/views/index.haml +1 -1
- data/sinatra-cometio.gemspec +1 -1
- data/test/app/config.ru +1 -1
- data/test/app/main.rb +21 -17
- data/test/test_cometio.rb +5 -0
- metadata +4 -3
- data/lib/sinatra/application.rb +0 -67
data/History.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
=== 0.1.6 2013-3-3
|
2
|
+
|
3
|
+
* add IO close function - CometIO.close()
|
4
|
+
* set :cometio, :xhr_interval => 15
|
5
|
+
* use Sinatra.register
|
6
|
+
|
1
7
|
=== 0.1.5 2013-3-3
|
2
8
|
|
3
9
|
* add tests with ruby client
|
@@ -17,7 +23,7 @@
|
|
17
23
|
|
18
24
|
=== 0.1.1 2013-2-7
|
19
25
|
|
20
|
-
* fix
|
26
|
+
* little fix
|
21
27
|
|
22
28
|
=== 0.1.0 2013-2-6
|
23
29
|
|
data/README.md
CHANGED
@@ -132,6 +132,20 @@ or
|
|
132
132
|
io.removeListener("error"); // remove all "error" listener
|
133
133
|
```
|
134
134
|
|
135
|
+
Config
|
136
|
+
------
|
137
|
+
|
138
|
+
config.ru
|
139
|
+
```ruby
|
140
|
+
require 'sinatra'
|
141
|
+
require 'sinatra/cometio'
|
142
|
+
require File.dirname(__FILE__)+'/main'
|
143
|
+
|
144
|
+
set :cometio, :xhr_interval => 20
|
145
|
+
|
146
|
+
run Sinatra::Application
|
147
|
+
```
|
148
|
+
|
135
149
|
Sample App
|
136
150
|
----------
|
137
151
|
chat app
|
data/lib/js/cometio.js
CHANGED
@@ -2,6 +2,7 @@ var CometIO = function(){
|
|
2
2
|
new EventEmitter().apply(this);
|
3
3
|
this.url = "<%= cometio_url %>";
|
4
4
|
this.session = null;
|
5
|
+
var running = false;
|
5
6
|
var self = this;
|
6
7
|
|
7
8
|
this.push = function(type, data){
|
@@ -24,15 +25,23 @@ var CometIO = function(){
|
|
24
25
|
};
|
25
26
|
|
26
27
|
this.connect = function(){
|
28
|
+
if(running) return self;
|
27
29
|
self.on("__session_id", function(session){
|
28
30
|
self.session = session;
|
29
31
|
self.emit("connect", self.session);
|
30
32
|
});
|
33
|
+
running = true;
|
31
34
|
self.get();
|
32
35
|
return self;
|
33
36
|
};
|
34
37
|
|
38
|
+
this.close = function(){
|
39
|
+
running = false;
|
40
|
+
self.removeListener("__session_id");
|
41
|
+
};
|
42
|
+
|
35
43
|
this.get = function(){
|
44
|
+
if(!running) return;
|
36
45
|
$.ajax(
|
37
46
|
{
|
38
47
|
url : self.url,
|
@@ -51,7 +60,7 @@ var CometIO = function(){
|
|
51
60
|
},
|
52
61
|
type : "GET",
|
53
62
|
dataType : "json",
|
54
|
-
timeout :
|
63
|
+
timeout : <%= (CometIO.options[:xhr_interval]+10)*1000 %>
|
55
64
|
}
|
56
65
|
);
|
57
66
|
};
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Sinatra::CometIO
|
2
|
+
|
3
|
+
def cometio=(options)
|
4
|
+
CometIO.options = options
|
5
|
+
end
|
6
|
+
|
7
|
+
def cometio
|
8
|
+
CometIO.options
|
9
|
+
end
|
10
|
+
|
11
|
+
helpers do
|
12
|
+
def cometio_js
|
13
|
+
"#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['SCRIPT_NAME']}/cometio/cometio.js"
|
14
|
+
end
|
15
|
+
|
16
|
+
def cometio_url
|
17
|
+
"#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['SCRIPT_NAME']}/cometio/io"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
get '/cometio/cometio.js' do
|
22
|
+
content_type 'application/javascript'
|
23
|
+
@js ||= (
|
24
|
+
js = ''
|
25
|
+
Dir.glob(File.expand_path '../js/*.js', File.dirname(__FILE__)).each do |i|
|
26
|
+
File.open(i) do |f|
|
27
|
+
js += f.read
|
28
|
+
end
|
29
|
+
end
|
30
|
+
ERB.new(js).result(binding)
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
get '/cometio/io' do
|
35
|
+
stream :keep_open do |s|
|
36
|
+
session = params[:session].to_s.empty? ? CometIO.create_session(request.ip) : params[:session]
|
37
|
+
CometIO.sessions[session][:stream] = s
|
38
|
+
CometIO.sessions[session][:last] = Time.now
|
39
|
+
CometIO.emit :connect, session if params[:session].to_s.empty?
|
40
|
+
|
41
|
+
unless CometIO.sessions[session][:queue].empty?
|
42
|
+
begin
|
43
|
+
s.write CometIO.sessions[session][:queue].shift.to_json
|
44
|
+
s.flush
|
45
|
+
s.close
|
46
|
+
rescue
|
47
|
+
s.close
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
EM::add_timer CometIO.options[:xhr_interval] do
|
52
|
+
begin
|
53
|
+
s.write({:type => :__heartbeat, :data => {:time => Time.now.to_i}}.to_json)
|
54
|
+
s.flush
|
55
|
+
s.close
|
56
|
+
rescue
|
57
|
+
s.close
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
post '/cometio/io' do
|
64
|
+
type = params[:type]
|
65
|
+
data = params[:data]
|
66
|
+
from = params[:session]
|
67
|
+
CometIO.emit type, data, from if type.to_s.size > 0
|
68
|
+
{:session => from, :type => type, :data => data}.to_json
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class CometIO
|
2
|
+
|
3
|
+
def self.default_options
|
4
|
+
{
|
5
|
+
:xhr_interval => [15, lambda{|v| v.kind_of? Fixnum and v >= 10 }]
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.options
|
10
|
+
@@options ||= (
|
11
|
+
opts = {}
|
12
|
+
default_options.each do |k,v|
|
13
|
+
opts[k] = v[0]
|
14
|
+
end
|
15
|
+
opts
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.options=(opts)
|
20
|
+
@@options = {}
|
21
|
+
opts.each do |k,v|
|
22
|
+
k = k.to_sym
|
23
|
+
if default_options.include? k
|
24
|
+
@@options[k] = default_options[k][1].call(v) ? v : default_options[k][0]
|
25
|
+
else
|
26
|
+
@@options[k] = v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
default_options.each do |k, v|
|
30
|
+
@@options[k] = v unless @@options.include? k
|
31
|
+
end
|
32
|
+
@@options
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/sinatra/cometio.rb
CHANGED
@@ -3,8 +3,10 @@ require 'json'
|
|
3
3
|
require 'digest/md5'
|
4
4
|
require 'event_emitter'
|
5
5
|
require 'sinatra/streaming'
|
6
|
-
require File.expand_path 'application', File.dirname(__FILE__)
|
7
6
|
require File.expand_path '../sinatra-cometio/version', File.dirname(__FILE__)
|
7
|
+
require File.expand_path '../sinatra-cometio/options', File.dirname(__FILE__)
|
8
|
+
require File.expand_path '../sinatra-cometio/application', File.dirname(__FILE__)
|
9
|
+
Sinatra.register Sinatra::CometIO
|
8
10
|
|
9
11
|
class CometIO
|
10
12
|
def self.sessions
|
@@ -19,7 +21,7 @@ class CometIO
|
|
19
21
|
|
20
22
|
def self.gc
|
21
23
|
self.sessions.each do |id, s|
|
22
|
-
next unless s[:last] and s[:last] < Time.now-
|
24
|
+
next unless s[:last] and s[:last] < Time.now-CometIO.options[:xhr_interval]*2-10
|
23
25
|
self.sessions.delete id rescue next
|
24
26
|
self.emit :disconnect, id
|
25
27
|
end
|
@@ -28,7 +30,7 @@ class CometIO
|
|
28
30
|
EM::defer do
|
29
31
|
loop do
|
30
32
|
self.gc
|
31
|
-
sleep
|
33
|
+
sleep CometIO.options[:xhr_interval]+5
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -15,6 +15,7 @@ class CometIO
|
|
15
15
|
raise ArgumentError, "invalid URL (#{url})" unless url.kind_of? String and url =~ /^https?:\/\/.+/
|
16
16
|
@url = url
|
17
17
|
@session = nil
|
18
|
+
@running = false
|
18
19
|
end
|
19
20
|
|
20
21
|
def push(type, data)
|
@@ -28,18 +29,25 @@ class CometIO
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def connect
|
32
|
+
return self if @running
|
31
33
|
self.on :__session_id do |session|
|
32
34
|
@session = session
|
33
35
|
self.emit :connect, @session
|
34
36
|
end
|
37
|
+
@running = true
|
35
38
|
get
|
36
39
|
return self
|
37
40
|
end
|
38
41
|
|
42
|
+
def close
|
43
|
+
@running = false
|
44
|
+
self.remove_listener :__session_id
|
45
|
+
end
|
46
|
+
|
39
47
|
private
|
40
48
|
def get
|
41
49
|
Thread.new do
|
42
|
-
|
50
|
+
while @running do
|
43
51
|
begin
|
44
52
|
res = HTTParty.get "#{@url}?session=#{@session}", :timeout => 60000
|
45
53
|
unless res.code == 200
|
data/sample/config.ru
CHANGED
data/sample/main.rb
CHANGED
data/sample/views/index.haml
CHANGED
data/sinatra-cometio.gemspec
CHANGED
@@ -4,7 +4,7 @@ require 'sinatra-cometio/version'
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = "sinatra-cometio"
|
7
|
-
gem.version =
|
7
|
+
gem.version = Sinatra::CometIO::VERSION
|
8
8
|
gem.authors = ["Sho Hashimoto"]
|
9
9
|
gem.email = ["hashimoto@shokai.org"]
|
10
10
|
gem.description = %q{Node.js like Comet I/O plugin for Sinatra.}
|
data/test/app/config.ru
CHANGED
data/test/app/main.rb
CHANGED
@@ -3,25 +3,29 @@ File.open(pid_file, "w+") do |f|
|
|
3
3
|
f.write Process.pid.to_s
|
4
4
|
end
|
5
5
|
|
6
|
-
|
7
|
-
"sinatra-cometio v#{SinatraCometIO::VERSION}"
|
8
|
-
end
|
6
|
+
class TestApp < Sinatra::Application
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
end
|
8
|
+
get '/' do
|
9
|
+
"sinatra-cometio v#{Sinatra::CometIO::VERSION}"
|
10
|
+
end
|
13
11
|
|
14
|
-
CometIO.on :
|
15
|
-
|
16
|
-
end
|
12
|
+
CometIO.on :connect do |session|
|
13
|
+
puts "new client <#{session}>"
|
14
|
+
end
|
17
15
|
|
18
|
-
CometIO.on :
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
CometIO.on :disconnect do |session|
|
17
|
+
puts "disconnect client <#{session}>"
|
18
|
+
end
|
19
|
+
|
20
|
+
CometIO.on :broadcast do |data, from|
|
21
|
+
puts from
|
22
|
+
puts "broadcast <#{from}> - #{data.to_json}"
|
23
|
+
push :broadcast, data
|
24
|
+
end
|
25
|
+
|
26
|
+
CometIO.on :message do |data, from|
|
27
|
+
puts "message <#{from}> - #{data.to_json}"
|
28
|
+
push :message, data, :to => data['to']
|
29
|
+
end
|
23
30
|
|
24
|
-
CometIO.on :message do |data, from|
|
25
|
-
puts "message <#{from}> - #{data.to_json}"
|
26
|
-
push :message, data, :to => data['to']
|
27
31
|
end
|
data/test/test_cometio.rb
CHANGED
@@ -26,6 +26,7 @@ class TestCometio < MiniTest::Unit::TestCase
|
|
26
26
|
break if res != nil
|
27
27
|
sleep 0.1
|
28
28
|
end
|
29
|
+
client.close
|
29
30
|
assert res != nil, 'server not respond'
|
30
31
|
assert res["time"] == post_data[:time]
|
31
32
|
assert res["msg"] == post_data[:msg]
|
@@ -50,6 +51,8 @@ class TestCometio < MiniTest::Unit::TestCase
|
|
50
51
|
end
|
51
52
|
client2.on :message do |data|
|
52
53
|
res2 = data
|
54
|
+
client2.close
|
55
|
+
client.close
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
@@ -71,6 +74,7 @@ class TestCometio < MiniTest::Unit::TestCase
|
|
71
74
|
res = nil
|
72
75
|
client.on :broadcast do |data|
|
73
76
|
res = data
|
77
|
+
client.close
|
74
78
|
end
|
75
79
|
|
76
80
|
res2 = nil
|
@@ -81,6 +85,7 @@ class TestCometio < MiniTest::Unit::TestCase
|
|
81
85
|
end
|
82
86
|
client2.on :broadcast do |data|
|
83
87
|
res2 = data
|
88
|
+
client2.close
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-cometio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -139,8 +139,9 @@ files:
|
|
139
139
|
- lib/js/cometio.js
|
140
140
|
- lib/js/event_emitter.js
|
141
141
|
- lib/sinatra-cometio.rb
|
142
|
+
- lib/sinatra-cometio/application.rb
|
143
|
+
- lib/sinatra-cometio/options.rb
|
142
144
|
- lib/sinatra-cometio/version.rb
|
143
|
-
- lib/sinatra/application.rb
|
144
145
|
- lib/sinatra/cometio.rb
|
145
146
|
- lib/sinatra/cometio/client.rb
|
146
147
|
- sample/.gitignore
|
data/lib/sinatra/application.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
module Sinatra
|
2
|
-
|
3
|
-
class Application
|
4
|
-
|
5
|
-
helpers do
|
6
|
-
def cometio_js
|
7
|
-
"#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['SCRIPT_NAME']}/cometio/cometio.js"
|
8
|
-
end
|
9
|
-
|
10
|
-
def cometio_url
|
11
|
-
"#{env['rack.url_scheme']}://#{env['HTTP_HOST']}#{env['SCRIPT_NAME']}/cometio/io"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
get '/cometio/cometio.js' do
|
16
|
-
content_type 'application/javascript'
|
17
|
-
@js ||= (
|
18
|
-
js = ''
|
19
|
-
Dir.glob(File.expand_path '../js/*.js', File.dirname(__FILE__)).each do |i|
|
20
|
-
File.open(i) do |f|
|
21
|
-
js += f.read
|
22
|
-
end
|
23
|
-
end
|
24
|
-
ERB.new(js).result(binding)
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
get '/cometio/io' do
|
29
|
-
stream :keep_open do |s|
|
30
|
-
session = params[:session].to_s.empty? ? CometIO.create_session(request.ip) : params[:session]
|
31
|
-
CometIO.sessions[session][:stream] = s
|
32
|
-
CometIO.sessions[session][:last] = Time.now
|
33
|
-
CometIO.emit :connect, session if params[:session].to_s.empty?
|
34
|
-
|
35
|
-
unless CometIO.sessions[session][:queue].empty?
|
36
|
-
begin
|
37
|
-
s.write CometIO.sessions[session][:queue].shift.to_json
|
38
|
-
s.flush
|
39
|
-
s.close
|
40
|
-
rescue
|
41
|
-
s.close
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
EM::add_timer 10 do
|
46
|
-
begin
|
47
|
-
s.write({:type => :__heartbeat, :data => {:time => Time.now.to_i}}.to_json)
|
48
|
-
s.flush
|
49
|
-
s.close
|
50
|
-
rescue
|
51
|
-
s.close
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
post '/cometio/io' do
|
58
|
-
type = params[:type]
|
59
|
-
data = params[:data]
|
60
|
-
from = params[:session]
|
61
|
-
CometIO.emit type, data, from if type.to_s.size > 0
|
62
|
-
{:session => from, :type => type, :data => data}.to_json
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|