sinatra-rocketio 0.0.1
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/.gitignore +23 -0
- data/Gemfile +4 -0
- data/History.txt +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +159 -0
- data/Rakefile +1 -0
- data/lib/js/event_emitter.js +68 -0
- data/lib/js/rocketio.js +48 -0
- data/lib/sinatra-rocketio.rb +7 -0
- data/lib/sinatra-rocketio/application.rb +16 -0
- data/lib/sinatra-rocketio/helpers.rb +11 -0
- data/lib/sinatra-rocketio/javascript.rb +25 -0
- data/lib/sinatra-rocketio/options.rb +44 -0
- data/lib/sinatra-rocketio/rocketio.rb +32 -0
- data/lib/sinatra-rocketio/version.rb +5 -0
- data/lib/sinatra/rocketio.rb +15 -0
- data/sample/Gemfile +10 -0
- data/sample/Gemfile.lock +82 -0
- data/sample/Procfile +1 -0
- data/sample/README.md +34 -0
- data/sample/bin/cui_chat_client.rb +38 -0
- data/sample/config.ru +23 -0
- data/sample/main.rb +32 -0
- data/sample/public/js/index.js +38 -0
- data/sample/views/index.haml +27 -0
- data/sample/views/main.scss +15 -0
- data/sinatra-rocketio.gemspec +24 -0
- metadata +168 -0
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
.DS_Store
|
2
|
+
*.tmp
|
3
|
+
*~
|
4
|
+
*#*
|
5
|
+
vendor
|
6
|
+
.sass-cache
|
7
|
+
.bundle
|
8
|
+
config.yml
|
9
|
+
*.gem
|
10
|
+
*.rbc
|
11
|
+
.config
|
12
|
+
.yardoc
|
13
|
+
InstalledFiles
|
14
|
+
_yardoc
|
15
|
+
coverage
|
16
|
+
doc/
|
17
|
+
lib/bundler/man
|
18
|
+
pkg
|
19
|
+
rdoc
|
20
|
+
spec/reports
|
21
|
+
test/tmp
|
22
|
+
test/version_tmp
|
23
|
+
tmp
|
data/Gemfile
ADDED
data/History.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Sho Hashimoto
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
sinatra-rocketio
|
2
|
+
================
|
3
|
+
|
4
|
+
* Node.js like I/O plugin for Sinatra.
|
5
|
+
* Automatically selects from Comet and WebSocket.
|
6
|
+
* https://github.com/shokai/sinatra-rocketio
|
7
|
+
* [Handle 10K+ clients on 1 process](https://github.com/shokai/sinatra-websocketio/wiki/C10K)
|
8
|
+
|
9
|
+
|
10
|
+
Installation
|
11
|
+
------------
|
12
|
+
|
13
|
+
gem install sinatra-rocketio
|
14
|
+
|
15
|
+
|
16
|
+
Requirements
|
17
|
+
------------
|
18
|
+
* Ruby 1.8.7 or 1.9.2 or 1.9.3 or 2.0.0
|
19
|
+
* Sinatra 1.3.0+
|
20
|
+
* EventMachine
|
21
|
+
* jQuery
|
22
|
+
|
23
|
+
|
24
|
+
Usage
|
25
|
+
-----
|
26
|
+
### Server --(WebSocket/Comet)--> Client
|
27
|
+
|
28
|
+
Server Side
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'sinatra'
|
32
|
+
require 'sinatra/rocketio'
|
33
|
+
set :cometio, :timeout => 120
|
34
|
+
set :websocketio, :port => 8080
|
35
|
+
|
36
|
+
run Sinatra::Application
|
37
|
+
```
|
38
|
+
```ruby
|
39
|
+
io = Sinatra::RocketIO
|
40
|
+
|
41
|
+
io.push :temperature, 35 # to all clients
|
42
|
+
io.push :light, {:value => 150}, {:to => session_id} # to specific client
|
43
|
+
```
|
44
|
+
|
45
|
+
Client Side
|
46
|
+
|
47
|
+
```html
|
48
|
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
49
|
+
<script src="<%= rocketio_js %>"></script>
|
50
|
+
```
|
51
|
+
```javascript
|
52
|
+
var io = new RocketIO().connect();
|
53
|
+
io.on("temperature", function(value){
|
54
|
+
console.log("server temperature : " + value);
|
55
|
+
}); // => "server temperature : 35"
|
56
|
+
io.on("light", function(data){
|
57
|
+
console.log("server light sensor : " + data.value);
|
58
|
+
}); // => "server light sensor : 150"
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
### Client --(WebSocket/Ajax)--> Server
|
63
|
+
|
64
|
+
Client Side
|
65
|
+
|
66
|
+
```javascript
|
67
|
+
io.push("chat", {name: "shokai", message: "hello"}); // client -> server
|
68
|
+
```
|
69
|
+
|
70
|
+
Server Side
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
io.on :chat do |data, session, type|
|
74
|
+
puts "#{data['name']} : #{data['message']} <#{session}> type:#{type}"
|
75
|
+
end
|
76
|
+
## => "shokai : hello <12abcde345f6g7h8ijk> type:websocket"
|
77
|
+
```
|
78
|
+
|
79
|
+
### On "connect" Event
|
80
|
+
|
81
|
+
Client Side
|
82
|
+
|
83
|
+
```javascript
|
84
|
+
io.on("connect", function(session){
|
85
|
+
alert("connect!!");
|
86
|
+
});
|
87
|
+
```
|
88
|
+
|
89
|
+
Server Side
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
io.on :connect do |session, type|
|
93
|
+
puts "new client <#{session}> type:#{type}"
|
94
|
+
end
|
95
|
+
|
96
|
+
io.on :disconnect do |session, type|
|
97
|
+
puts "client disconnected <#{session}> type:#{type}"
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
### On "error" Event
|
102
|
+
|
103
|
+
Client Side
|
104
|
+
|
105
|
+
```javascript
|
106
|
+
io.on("error", function(err){
|
107
|
+
console.error(err);
|
108
|
+
});
|
109
|
+
```
|
110
|
+
|
111
|
+
### Remove Event Listener
|
112
|
+
|
113
|
+
Server Side
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
event_id = io.on :chat do |data, from, type|
|
117
|
+
puts "#{data} - from:#{from} type:#{type}"
|
118
|
+
end
|
119
|
+
io.removeListener event_id
|
120
|
+
```
|
121
|
+
|
122
|
+
or
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
io.removeListener :chat # remove all "chat" listener
|
126
|
+
```
|
127
|
+
|
128
|
+
|
129
|
+
Client Side
|
130
|
+
|
131
|
+
```javascript
|
132
|
+
var event_id = io.on("error", function(err){
|
133
|
+
console.error("RocketIO error : "err);
|
134
|
+
});
|
135
|
+
io.removeListener(event_id);
|
136
|
+
```
|
137
|
+
|
138
|
+
or
|
139
|
+
|
140
|
+
```javascript
|
141
|
+
io.removeListener("error"); // remove all "error" listener
|
142
|
+
```
|
143
|
+
|
144
|
+
|
145
|
+
Sample App
|
146
|
+
----------
|
147
|
+
chat app
|
148
|
+
|
149
|
+
- https://github.com/shokai/sinatra-rocketio/tree/master/sample
|
150
|
+
|
151
|
+
|
152
|
+
Contributing
|
153
|
+
------------
|
154
|
+
|
155
|
+
1. Fork it
|
156
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
157
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
158
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
159
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,68 @@
|
|
1
|
+
// event_emitter.js v0.0.6
|
2
|
+
// https://github.com/shokai/event_emitter.js
|
3
|
+
// (c) 2013 Sho Hashimoto <hashimoto@shokai.org>
|
4
|
+
// The MIT License
|
5
|
+
var EventEmitter = function(){
|
6
|
+
var self = this;
|
7
|
+
this.apply = function(target, prefix){
|
8
|
+
if(!prefix) prefix = "";
|
9
|
+
for(var func in self){
|
10
|
+
if(self.hasOwnProperty(func)){
|
11
|
+
target[prefix+func] = this[func];
|
12
|
+
}
|
13
|
+
}
|
14
|
+
};
|
15
|
+
this.__events = new Array();
|
16
|
+
this.on = function(type, listener, opts){
|
17
|
+
if(typeof listener !== "function") return;
|
18
|
+
var event_id = self.__events.length > 0 ? 1 + self.__events[self.__events.length-1].id : 0
|
19
|
+
var params = {
|
20
|
+
id: event_id,
|
21
|
+
type: type,
|
22
|
+
listener: listener
|
23
|
+
};
|
24
|
+
for(i in opts){
|
25
|
+
if(!params[i]) params[i] = opts[i];
|
26
|
+
};
|
27
|
+
self.__events.push(params);
|
28
|
+
return event_id;
|
29
|
+
};
|
30
|
+
|
31
|
+
this.once = function(type, listener){
|
32
|
+
self.on(type, listener, {once: true});
|
33
|
+
};
|
34
|
+
|
35
|
+
this.emit = function(type, data){
|
36
|
+
for(var i = 0; i < self.__events.length; i++){
|
37
|
+
var e = self.__events[i];
|
38
|
+
switch(e.type){
|
39
|
+
case type:
|
40
|
+
e.listener(data);
|
41
|
+
break
|
42
|
+
case '*':
|
43
|
+
e.listener(type, data);
|
44
|
+
break
|
45
|
+
}
|
46
|
+
if(e.once) self.removeListener(e.id);
|
47
|
+
}
|
48
|
+
};
|
49
|
+
|
50
|
+
this.removeListener = function(id_or_type){
|
51
|
+
for(var i = self.__events.length-1; i >= 0; i--){
|
52
|
+
var e = self.__events[i];
|
53
|
+
switch(typeof id_or_type){
|
54
|
+
case "number":
|
55
|
+
if(e.id == id_or_type) self.__events.splice(i,1);
|
56
|
+
break
|
57
|
+
case "string":
|
58
|
+
if(e.type == id_or_type) self.__events.splice(i,1);
|
59
|
+
break
|
60
|
+
}
|
61
|
+
}
|
62
|
+
};
|
63
|
+
|
64
|
+
};
|
65
|
+
|
66
|
+
if(typeof module !== 'undefined' && typeof module.exports !== 'undefined'){
|
67
|
+
module.exports = EventEmitter;
|
68
|
+
}
|
data/lib/js/rocketio.js
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
var RocketIO = function(){
|
2
|
+
new EventEmitter().apply(this);
|
3
|
+
this.type = null; // comet, websocket
|
4
|
+
this.session = null;
|
5
|
+
this.io = null;
|
6
|
+
var self = this;
|
7
|
+
var ws_close_timer = null;
|
8
|
+
|
9
|
+
this.connect = function(){
|
10
|
+
self.io = function(){
|
11
|
+
if(self.type === "comet") return;
|
12
|
+
var io = new WebSocketIO();
|
13
|
+
io.session = self.session;
|
14
|
+
return io.connect();
|
15
|
+
}() || function(){
|
16
|
+
var io = new CometIO();
|
17
|
+
io.session = self.session;
|
18
|
+
return io.connect();
|
19
|
+
}();
|
20
|
+
if(self.io.url.match(/^ws:\/\/.+/)) self.type = "websocket";
|
21
|
+
else if(self.io.url.match(/cometio/)) self.type = "comet";
|
22
|
+
else self.type = "unknown";
|
23
|
+
self.io.on("*", function(event_name, args){
|
24
|
+
self.emit(event_name, args);
|
25
|
+
});
|
26
|
+
self.io.on("connect", function(session_id){
|
27
|
+
self.session = session_id;
|
28
|
+
});
|
29
|
+
ws_close_timer = setTimeout(function(){
|
30
|
+
self.close();
|
31
|
+
self.type = "comet";
|
32
|
+
self.connect();
|
33
|
+
}, 3000);
|
34
|
+
return self;
|
35
|
+
};
|
36
|
+
|
37
|
+
self.on("connect", function(){
|
38
|
+
clearTimeout(ws_close_timer);
|
39
|
+
});
|
40
|
+
|
41
|
+
this.close = function(){
|
42
|
+
self.io.close();
|
43
|
+
};
|
44
|
+
|
45
|
+
this.push = function(type, data){
|
46
|
+
self.io.push(type, data);
|
47
|
+
};
|
48
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
|
4
|
+
def self.registered(app)
|
5
|
+
app.register Sinatra::CometIO
|
6
|
+
app.register Sinatra::WebSocketIO
|
7
|
+
app.helpers Sinatra::RocketIO::Helpers
|
8
|
+
|
9
|
+
app.get '/rocketio/rocketio.js' do
|
10
|
+
content_type 'application/javascript'
|
11
|
+
@js ||= ERB.new(Sinatra::RocketIO.javascript).result(binding)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
|
4
|
+
def self.javascript(*js_file_names)
|
5
|
+
js_file_names = ['rocketio.js', 'cometio.js', 'websocketio.js', 'event_emitter.js']
|
6
|
+
js = ''
|
7
|
+
js_file_names.each do |i|
|
8
|
+
js += case i
|
9
|
+
when 'cometio.js'
|
10
|
+
Sinatra::CometIO.javascript 'cometio.js'
|
11
|
+
when 'websocketio.js'
|
12
|
+
Sinatra::WebSocketIO.javascript 'websocketio.js'
|
13
|
+
else
|
14
|
+
j = ''
|
15
|
+
File.open(File.expand_path "../js/#{i}", File.dirname(__FILE__)) do |f|
|
16
|
+
j = f.read
|
17
|
+
end
|
18
|
+
j
|
19
|
+
end + "\n"
|
20
|
+
end
|
21
|
+
js
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
|
4
|
+
def rocketio=(options)
|
5
|
+
RocketIO.options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def rocketio
|
9
|
+
RocketIO.options
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.default_options
|
13
|
+
{
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.options
|
18
|
+
@@options ||= (
|
19
|
+
opts = {}
|
20
|
+
default_options.each do |k,v|
|
21
|
+
opts[k] = v[0]
|
22
|
+
end
|
23
|
+
opts
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.options=(opts)
|
28
|
+
@@options = {}
|
29
|
+
opts.each do |k,v|
|
30
|
+
k = k.to_sym
|
31
|
+
if default_options.include? k
|
32
|
+
@@options[k] = default_options[k][1].call(v) ? v : default_options[k][0]
|
33
|
+
else
|
34
|
+
@@options[k] = v
|
35
|
+
end
|
36
|
+
end
|
37
|
+
default_options.each do |k, v|
|
38
|
+
@@options[k] = v unless @@options.include? k
|
39
|
+
end
|
40
|
+
@@options
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module RocketIO
|
3
|
+
|
4
|
+
def self.push(type, data, opt={})
|
5
|
+
Sinatra::CometIO.push type, data, opt
|
6
|
+
Sinatra::WebSocketIO.push type, data, opt
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.sessions
|
10
|
+
{
|
11
|
+
:websocket => Sinatra::WebSocketIO.sessions,
|
12
|
+
:comet => Sinatra::CometIO.sessions
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
EventEmitter.apply Sinatra::RocketIO
|
19
|
+
Sinatra::CometIO.on :* do |event_name, *args|
|
20
|
+
if args.size > 1
|
21
|
+
Sinatra::RocketIO.emit event_name, args[0], args[1], :comet
|
22
|
+
else
|
23
|
+
Sinatra::RocketIO.emit event_name, args[0], :comet
|
24
|
+
end
|
25
|
+
end
|
26
|
+
Sinatra::WebSocketIO.on :* do |event_name, *args|
|
27
|
+
if args.size > 1
|
28
|
+
Sinatra::RocketIO.emit event_name, args[0], args[1], :websocket
|
29
|
+
else
|
30
|
+
Sinatra::RocketIO.emit event_name, args[0], :websocket
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'sinatra/cometio'
|
3
|
+
require 'sinatra/websocketio'
|
4
|
+
require File.expand_path '../sinatra-rocketio/version', File.dirname(__FILE__)
|
5
|
+
require File.expand_path '../sinatra-rocketio/helpers', File.dirname(__FILE__)
|
6
|
+
require File.expand_path '../sinatra-rocketio/options', File.dirname(__FILE__)
|
7
|
+
require File.expand_path '../sinatra-rocketio/rocketio', File.dirname(__FILE__)
|
8
|
+
require File.expand_path '../sinatra-rocketio/javascript', File.dirname(__FILE__)
|
9
|
+
require File.expand_path '../sinatra-rocketio/application', File.dirname(__FILE__)
|
10
|
+
|
11
|
+
module Sinatra
|
12
|
+
module RocketIO
|
13
|
+
end
|
14
|
+
register RocketIO
|
15
|
+
end
|
data/sample/Gemfile
ADDED
data/sample/Gemfile.lock
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.3)
|
5
|
+
backports (3.1.1)
|
6
|
+
daemons (1.1.9)
|
7
|
+
em-websocket (0.5.0)
|
8
|
+
eventmachine (>= 0.12.9)
|
9
|
+
http_parser.rb (~> 0.5.3)
|
10
|
+
em-websocket-client (0.1.1)
|
11
|
+
eventmachine
|
12
|
+
libwebsocket
|
13
|
+
event_emitter (0.2.3)
|
14
|
+
eventmachine (1.0.3)
|
15
|
+
foreman (0.62.0)
|
16
|
+
thor (>= 0.13.6)
|
17
|
+
haml (4.0.0)
|
18
|
+
tilt
|
19
|
+
http_parser.rb (0.5.3)
|
20
|
+
httparty (0.10.2)
|
21
|
+
multi_json (~> 1.0)
|
22
|
+
multi_xml (>= 0.5.2)
|
23
|
+
json (1.7.7)
|
24
|
+
libwebsocket (0.1.7.1)
|
25
|
+
addressable
|
26
|
+
websocket
|
27
|
+
multi_json (1.7.0)
|
28
|
+
multi_xml (0.5.3)
|
29
|
+
rack (1.5.2)
|
30
|
+
rack-protection (1.5.0)
|
31
|
+
rack
|
32
|
+
rack-test (0.6.2)
|
33
|
+
rack (>= 1.0)
|
34
|
+
sass (3.2.7)
|
35
|
+
sinatra (1.3.6)
|
36
|
+
rack (~> 1.4)
|
37
|
+
rack-protection (~> 1.3)
|
38
|
+
tilt (~> 1.3, >= 1.3.3)
|
39
|
+
sinatra-cometio (0.3.3)
|
40
|
+
event_emitter (>= 0.2.0)
|
41
|
+
eventmachine
|
42
|
+
httparty
|
43
|
+
json
|
44
|
+
rack
|
45
|
+
sinatra
|
46
|
+
sinatra-contrib
|
47
|
+
sinatra-contrib (1.3.2)
|
48
|
+
backports (>= 2.0)
|
49
|
+
eventmachine
|
50
|
+
rack-protection
|
51
|
+
rack-test
|
52
|
+
sinatra (~> 1.3.0)
|
53
|
+
tilt (~> 1.3)
|
54
|
+
sinatra-websocketio (0.1.1)
|
55
|
+
em-websocket
|
56
|
+
em-websocket-client
|
57
|
+
event_emitter (>= 0.2.0)
|
58
|
+
eventmachine
|
59
|
+
json
|
60
|
+
rack
|
61
|
+
sinatra
|
62
|
+
sinatra-contrib
|
63
|
+
thin (1.5.0)
|
64
|
+
daemons (>= 1.0.9)
|
65
|
+
eventmachine (>= 0.12.6)
|
66
|
+
rack (>= 1.0.0)
|
67
|
+
thor (0.17.0)
|
68
|
+
tilt (1.3.5)
|
69
|
+
websocket (1.0.7)
|
70
|
+
|
71
|
+
PLATFORMS
|
72
|
+
ruby
|
73
|
+
|
74
|
+
DEPENDENCIES
|
75
|
+
foreman
|
76
|
+
haml
|
77
|
+
rack
|
78
|
+
sass
|
79
|
+
sinatra
|
80
|
+
sinatra-cometio
|
81
|
+
sinatra-websocketio
|
82
|
+
thin
|
data/sample/Procfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec rackup config.ru -p $PORT
|
data/sample/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
WebSocket/Comet Chat
|
2
|
+
====================
|
3
|
+
|
4
|
+
* Ruby 1.8.7 or 1.9.2 or 1.9.3 or 2.0.0
|
5
|
+
* sinatra-rocketio with Sinatra1.3+
|
6
|
+
|
7
|
+
|
8
|
+
Install Dependencies
|
9
|
+
--------------------
|
10
|
+
|
11
|
+
% gem install bundler foreman
|
12
|
+
% bundle install
|
13
|
+
|
14
|
+
|
15
|
+
Run
|
16
|
+
---
|
17
|
+
|
18
|
+
% foreman start
|
19
|
+
|
20
|
+
=> http://localhost:5000
|
21
|
+
|
22
|
+
|
23
|
+
Deploy Heroku
|
24
|
+
-------------
|
25
|
+
|
26
|
+
% mkdir ~/rocketio-sample
|
27
|
+
% cp -R ./ ~/rocketio-sample/
|
28
|
+
% cd ~/rocketio-sample
|
29
|
+
% git init
|
30
|
+
% git add ./
|
31
|
+
% git commit -m "first sample chat"
|
32
|
+
% heroku create --stack cedar
|
33
|
+
% git push heroku master
|
34
|
+
% heroku open
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
$:.unshift File.expand_path '../../lib', File.dirname(__FILE__)
|
5
|
+
require 'eventmachine'
|
6
|
+
require 'em-websocketio-client'
|
7
|
+
|
8
|
+
name = `whoami`.strip || 'shokai'
|
9
|
+
|
10
|
+
EM::run do
|
11
|
+
client = EM::WebSocketIO::Client.new('ws://localhost:8080').connect
|
12
|
+
|
13
|
+
client.on :connect do |session|
|
14
|
+
puts "connect!! (session_id:#{session})"
|
15
|
+
end
|
16
|
+
|
17
|
+
client.on :chat do |data|
|
18
|
+
puts "<#{data['name']}> #{data['message']}"
|
19
|
+
end
|
20
|
+
|
21
|
+
client.on :error do |err|
|
22
|
+
STDERR.puts err
|
23
|
+
end
|
24
|
+
|
25
|
+
client.on :disconnect do
|
26
|
+
puts "disconnected!!"
|
27
|
+
end
|
28
|
+
|
29
|
+
EM::defer do
|
30
|
+
loop do
|
31
|
+
line = STDIN.gets.strip
|
32
|
+
next if line.empty?
|
33
|
+
client.push :chat, {:message => line, :name => name}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
data/sample/config.ru
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
Bundler.require
|
4
|
+
require 'sinatra/base'
|
5
|
+
if development?
|
6
|
+
$stdout.sync = true
|
7
|
+
require 'sinatra/reloader'
|
8
|
+
$:.unshift File.expand_path '../lib', File.dirname(__FILE__)
|
9
|
+
end
|
10
|
+
require 'sinatra/rocketio'
|
11
|
+
require File.dirname(__FILE__)+'/main'
|
12
|
+
|
13
|
+
set :haml, :escape_html => true
|
14
|
+
set :cometio, :timeout => 120
|
15
|
+
set :websocketio, :port => 8080
|
16
|
+
|
17
|
+
case RUBY_PLATFORM
|
18
|
+
when /linux/i then EM.epoll
|
19
|
+
when /bsd/i then EM.kqueue
|
20
|
+
end
|
21
|
+
EM.set_descriptor_table_size 10000
|
22
|
+
|
23
|
+
run ChatApp
|
data/sample/main.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
class ChatApp < Sinatra::Base
|
2
|
+
register Sinatra::RocketIO
|
3
|
+
io = Sinatra::RocketIO
|
4
|
+
|
5
|
+
io.on :connect do |session, type|
|
6
|
+
puts "new client <#{session}> (type:#{type})"
|
7
|
+
push :chat, {:name => "system", :message => "new #{type} client <#{session}>"}
|
8
|
+
push :chat, {:name => "system", :message => "welcome <#{session}>"}, {:to => session}
|
9
|
+
end
|
10
|
+
|
11
|
+
io.on :disconnect do |session, type|
|
12
|
+
puts "disconnect client <#{session}> (type:#{type})"
|
13
|
+
push :chat, {:name => "system", :message => "bye <#{session}>"}
|
14
|
+
end
|
15
|
+
|
16
|
+
io.on :chat do |data, from, type|
|
17
|
+
puts "#{data['name']} : #{data['message']} (from:#{from} type:#{type})"
|
18
|
+
push :chat, data
|
19
|
+
end
|
20
|
+
|
21
|
+
io.on :error do |err|
|
22
|
+
STDERR.puts "error!! #{err}"
|
23
|
+
end
|
24
|
+
|
25
|
+
get '/' do
|
26
|
+
haml :index
|
27
|
+
end
|
28
|
+
|
29
|
+
get '/:source.css' do
|
30
|
+
scss params[:source].to_sym
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
var io = new RocketIO().connect();
|
2
|
+
|
3
|
+
$(function(){
|
4
|
+
$("#chat #btn_send").click(post);
|
5
|
+
$("#chat #message").keydown(function(e){
|
6
|
+
if(e.keyCode == 13) post();
|
7
|
+
});
|
8
|
+
});
|
9
|
+
|
10
|
+
io.on("chat", function(data){
|
11
|
+
var m = $("<li>").text(data.name + " : " +data.message);
|
12
|
+
$("#chat #timeline").prepend(m);
|
13
|
+
});
|
14
|
+
|
15
|
+
io.on("connect", function(session){
|
16
|
+
console.log("connect!! "+session);
|
17
|
+
$("#type").text("type : "+io.type);
|
18
|
+
});
|
19
|
+
|
20
|
+
io.on("disconnect", function(session){
|
21
|
+
console.log("disconnect!!");
|
22
|
+
});
|
23
|
+
|
24
|
+
io.on("*", function(event, data){ // catch all events
|
25
|
+
console.log(event + " - " + JSON.stringify(data));
|
26
|
+
});
|
27
|
+
|
28
|
+
io.on("error", function(err){
|
29
|
+
console.error(err);
|
30
|
+
});
|
31
|
+
|
32
|
+
var post = function(){
|
33
|
+
var name = $("#chat #name").val();
|
34
|
+
var message = $("#chat #message").val();
|
35
|
+
if(message.length < 1) return;
|
36
|
+
io.push("chat", {name: name, message: message});
|
37
|
+
$("#chat #message").val("");
|
38
|
+
};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
!!! XHTML
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{'http-equiv' => 'Content-Type', :content => 'text/html', :charset => 'UTF-8'}
|
5
|
+
%title sinatra-rocketio chat
|
6
|
+
%link{:rel => 'stylesheet', :href => "/main.css", :type => 'text/css'}
|
7
|
+
%script{:type => 'text/javascript', :src => "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"}
|
8
|
+
%script{:type => 'text/javascript', :src => rocketio_js}
|
9
|
+
%script{:type => 'text/javascript', :src => "/js/index.js"}
|
10
|
+
|
11
|
+
%body
|
12
|
+
%div#content
|
13
|
+
%div#header
|
14
|
+
%h1 rocketio chat
|
15
|
+
%span#type
|
16
|
+
%div#main
|
17
|
+
%div#chat
|
18
|
+
%input{:id => 'name', :value => 'name', :size => 20}
|
19
|
+
%input{:id => 'message', :value => 'hello!!', :size => 80}
|
20
|
+
%input{:id => 'btn_send', :type => 'button', :value => 'post'}
|
21
|
+
%ul#timeline
|
22
|
+
|
23
|
+
%hr
|
24
|
+
%div#footer
|
25
|
+
sinatra-rocketio v#{Sinatra::RocketIO::VERSION} -
|
26
|
+
- src_url = 'https://github.com/shokai/sinatra-rocketio'
|
27
|
+
%a{:href => src_url} #{src_url}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'sinatra-rocketio/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "sinatra-rocketio"
|
7
|
+
gem.version = Sinatra::RocketIO::VERSION
|
8
|
+
gem.authors = ["Sho Hashimoto"]
|
9
|
+
gem.email = ["hashimoto@shokai.org"]
|
10
|
+
gem.description = %q{Node.js like I/O plugin for Sinatra}
|
11
|
+
gem.summary = gem.description
|
12
|
+
gem.homepage = "https://github.com/shokai/sinatra-rocketio"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/).reject{|i| i=="Gemfile.lock" }
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
gem.add_dependency "rack"
|
19
|
+
gem.add_dependency "sinatra"
|
20
|
+
gem.add_dependency "eventmachine"
|
21
|
+
gem.add_dependency "sinatra-contrib"
|
22
|
+
gem.add_dependency "sinatra-cometio"
|
23
|
+
gem.add_dependency "sinatra-websocketio"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-rocketio
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sho Hashimoto
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sinatra
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: eventmachine
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: sinatra-contrib
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: sinatra-cometio
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: sinatra-websocketio
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: Node.js like I/O plugin for Sinatra
|
111
|
+
email:
|
112
|
+
- hashimoto@shokai.org
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- .gitignore
|
118
|
+
- Gemfile
|
119
|
+
- History.txt
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- lib/js/event_emitter.js
|
124
|
+
- lib/js/rocketio.js
|
125
|
+
- lib/sinatra-rocketio.rb
|
126
|
+
- lib/sinatra-rocketio/application.rb
|
127
|
+
- lib/sinatra-rocketio/helpers.rb
|
128
|
+
- lib/sinatra-rocketio/javascript.rb
|
129
|
+
- lib/sinatra-rocketio/options.rb
|
130
|
+
- lib/sinatra-rocketio/rocketio.rb
|
131
|
+
- lib/sinatra-rocketio/version.rb
|
132
|
+
- lib/sinatra/rocketio.rb
|
133
|
+
- sample/Gemfile
|
134
|
+
- sample/Gemfile.lock
|
135
|
+
- sample/Procfile
|
136
|
+
- sample/README.md
|
137
|
+
- sample/bin/cui_chat_client.rb
|
138
|
+
- sample/config.ru
|
139
|
+
- sample/main.rb
|
140
|
+
- sample/public/js/index.js
|
141
|
+
- sample/views/index.haml
|
142
|
+
- sample/views/main.scss
|
143
|
+
- sinatra-rocketio.gemspec
|
144
|
+
homepage: https://github.com/shokai/sinatra-rocketio
|
145
|
+
licenses: []
|
146
|
+
post_install_message:
|
147
|
+
rdoc_options: []
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ! '>='
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
requirements: []
|
163
|
+
rubyforge_project:
|
164
|
+
rubygems_version: 1.8.24
|
165
|
+
signing_key:
|
166
|
+
specification_version: 3
|
167
|
+
summary: Node.js like I/O plugin for Sinatra
|
168
|
+
test_files: []
|