sinatra-cometio 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|