rocket 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.
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ *.rdb
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Araneo Ltd.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File without changes
@@ -0,0 +1,56 @@
1
+ # -*- ruby -*-
2
+
3
+ $:.unshift(File.expand_path('../lib', __FILE__))
4
+
5
+ require 'rspec/core/rake_task'
6
+ require 'rake/rdoctask'
7
+ require 'rocket/version'
8
+
9
+ SUMMARY = %Q{Event-oriented WebSockets server and toolkit.}
10
+ DESCRIPTION = %Q{
11
+ Rocket is a very fast and reliable web socket server built upon em-websockets library.
12
+ Rocket provides also JavaScript toolkit to serve up instructions to clients, and
13
+ ruby library which handles events triggering. This Project was strongly inspired
14
+ by awesome PusherApp.
15
+ }
16
+
17
+ begin
18
+ require 'jeweler'
19
+ Jeweler::Tasks.new do |g|
20
+ g.version = Rocket.version
21
+ g.name = "rocket"
22
+ g.email = "chris@nu7hat.ch"
23
+ g.homepage = "http://github.com/araneo/rocket"
24
+ g.authors = ["Araneo", "Chris Kowalik"]
25
+ g.summary = SUMMARY
26
+ g.description = DESCRIPTION
27
+ g.add_dependency "rocket-server", "0.0.1"
28
+ g.add_dependency "rocket-js", "0.0.1"
29
+ g.add_dependency "json", "~> 1.4"
30
+ g.add_development_dependency "rspec", "~> 2.0"
31
+ g.add_development_dependency "mocha", "~> 0.9"
32
+ end
33
+ Jeweler::GemcutterTasks.new
34
+ rescue
35
+ puts 'Jeweler is not available here'
36
+ end
37
+
38
+ RSpec::Core::RakeTask.new(:spec) do |t|
39
+ t.pattern = 'spec/**/*_spec.rb'
40
+ t.rspec_opts = %q[-Ilib -c -b]
41
+ end
42
+
43
+ RSpec::Core::RakeTask.new(:rcov) do |t|
44
+ t.rcov = true
45
+ t.rspec_opts = %q[-Ilib -c -b]
46
+ t.rcov_opts = %q[-Ilib -T -x "spec"]
47
+ end
48
+
49
+ Rake::RDocTask.new do |rdoc|
50
+ rdoc.title = "Rocket #{Rocket.version}"
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
55
+
56
+ task :default => :spec
@@ -0,0 +1 @@
1
+ #!/usr/bin/env ruby
@@ -0,0 +1,10 @@
1
+ module Rocket
2
+
3
+ autoload :Helpers, 'rocket/helpers'
4
+ autoload :Client, 'rocket/event'
5
+ autoload :Channel, 'rocket/channel'
6
+ autoload :WebSocket, 'rocket/websocket'
7
+
8
+ end # Rocket
9
+
10
+ require 'rocket/version'
@@ -0,0 +1,20 @@
1
+ require 'json'
2
+
3
+ module Rocket
4
+ class Channel
5
+
6
+ attr_reader :client
7
+
8
+ def initialize(client, channel)
9
+ @client = client
10
+ @channel = channel
11
+ end
12
+
13
+ def trigger(event, data)
14
+ client.connection do |socket|
15
+ socket.send({ :event => event, :channel => channel, :data => data }.to_json)
16
+ end
17
+ end
18
+
19
+ end # Channel
20
+ end # Rocket
@@ -0,0 +1,31 @@
1
+ require 'json'
2
+
3
+ module Rocket
4
+ # This Rocket client allows for triggering events via Rocket server.
5
+ #
6
+ # rocket = Rocket::Client.new("ws://host.com:9772", "my-app", "my53cr37k3y")
7
+ # rocket['my-channel'].trigger('event', { :hello => :world })
8
+ #
9
+ class Client
10
+
11
+ attr_reader :url
12
+ attr_reader :app_id
13
+ attr_reader :secret
14
+
15
+ def initialize(url, app_id, secret)
16
+ @url = File.join(url, 'app', app_id) + '?secret=' + secret
17
+ @app_id = app_id
18
+ end
19
+
20
+ def connection(&block)
21
+ socket = WebSocket.new(url)
22
+ yield(socket)
23
+ socket.close if socket && !socket.tcp_socket.closed?
24
+ end
25
+
26
+ def [](channel)
27
+ Channel.new(self, channel)
28
+ end
29
+
30
+ end # Client
31
+ end # Rocket
@@ -0,0 +1,23 @@
1
+ module Rocket
2
+ module Helpers
3
+
4
+ # Hash given, returns it version with symbolized keys.
5
+ #
6
+ # p symbolize_keys("hello" => "world", ["Array here"] => "yup")
7
+ # p symbolize_keys(:one => 1, "two" => 2)
8
+ #
9
+ # produces:
10
+ #
11
+ # {:hello => "world", ["Array here"] => "yup"}
12
+ # {:one => 1, :two => 2}
13
+ #
14
+ def symbolize_keys(hash)
15
+ return hash unless hash.is_a?(Hash)
16
+ hash.inject({}) do |options, (key, value)|
17
+ options[(key.to_sym if key.respond_to?(:to_sym)) || key] = value
18
+ options
19
+ end
20
+ end
21
+
22
+ end # Helpers
23
+ end # Rocket
@@ -0,0 +1,12 @@
1
+ module Rocket
2
+ module Version # :nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+ STRING = [MAJOR, MINOR, TINY].join(".")
7
+ end # Version
8
+
9
+ def self.version # :nodoc:
10
+ Version::STRING
11
+ end
12
+ end # Rocket
@@ -0,0 +1,225 @@
1
+ # Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
2
+ # Lincense: New BSD Lincense
3
+ # Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
4
+
5
+ require "socket"
6
+ require "uri"
7
+ require "digest/md5"
8
+ require "openssl"
9
+
10
+ module Rocket
11
+ class WebSocket
12
+
13
+ class Error < RuntimeError; end
14
+
15
+ class << self
16
+ attr_accessor :debug
17
+ end
18
+
19
+ attr_reader :header
20
+ attr_reader :path
21
+
22
+ def initialize(arg, params = {})
23
+ uri = arg.is_a?(String) ? URI.parse(arg) : arg
24
+
25
+ if uri.scheme == "ws"
26
+ default_port = 80
27
+ elsif uri.scheme = "wss"
28
+ default_port = 443
29
+ else
30
+ raise(WebSocket::Error, "unsupported scheme: #{uri.scheme}")
31
+ end
32
+
33
+ @path = (uri.path.empty? ? "/" : uri.path) + (uri.query ? "?" + uri.query : "")
34
+ host = uri.host + (uri.port == default_port ? "" : ":#{uri.port}")
35
+ origin = params[:origin] || "http://#{uri.host}"
36
+ key1 = generate_key()
37
+ key2 = generate_key()
38
+ key3 = generate_key3()
39
+
40
+ socket = TCPSocket.new(uri.host, uri.port || default_port)
41
+
42
+ if uri.scheme == "ws"
43
+ @socket = socket
44
+ else
45
+ @socket = ssl_handshake(socket)
46
+ end
47
+
48
+ write(
49
+ "GET #{@path} HTTP/1.1\r\n" +
50
+ "Upgrade: WebSocket\r\n" +
51
+ "Connection: Upgrade\r\n" +
52
+ "Host: #{host}\r\n" +
53
+ "Origin: #{origin}\r\n" +
54
+ "Sec-WebSocket-Key1: #{key1}\r\n" +
55
+ "Sec-WebSocket-Key2: #{key2}\r\n" +
56
+ "\r\n" +
57
+ "#{key3}")
58
+ flush()
59
+
60
+ line = gets().chomp()
61
+ raise(WebSocket::Error, "bad response: #{line}") if !(line =~ /\AHTTP\/1.1 101 /n)
62
+ read_header()
63
+ if @header["Sec-WebSocket-Origin"] != origin
64
+ raise(WebSocket::Error,
65
+ "origin doesn't match: '#{@header["WebSocket-Origin"]}' != '#{origin}'")
66
+ end
67
+ reply_digest = read(16)
68
+ expected_digest = security_digest(key1, key2, key3)
69
+ if reply_digest != expected_digest
70
+ raise(WebSocket::Error,
71
+ "security digest doesn't match: %p != %p" % [reply_digest, expected_digest])
72
+ end
73
+ @handshaked = true
74
+ @closing_started = false
75
+ end
76
+
77
+ def send(data)
78
+ if !@handshaked
79
+ raise(WebSocket::Error, "call WebSocket\#handshake first")
80
+ end
81
+ data = force_encoding(data.dup(), "ASCII-8BIT")
82
+ write("\x00#{data}\xff")
83
+ flush()
84
+ end
85
+
86
+ def receive()
87
+ if !@handshaked
88
+ raise(WebSocket::Error, "call WebSocket\#handshake first")
89
+ end
90
+ packet = gets("\xff")
91
+ return nil if !packet
92
+ if packet =~ /\A\x00(.*)\xff\z/nm
93
+ return force_encoding($1, "UTF-8")
94
+ elsif packet == "\xff" && read(1) == "\x00" # closing
95
+ if @server
96
+ @socket.close()
97
+ else
98
+ close()
99
+ end
100
+ return nil
101
+ else
102
+ raise(WebSocket::Error, "input must be either '\\x00...\\xff' or '\\xff\\x00'")
103
+ end
104
+ end
105
+
106
+ def tcp_socket
107
+ return @socket
108
+ end
109
+
110
+ def host
111
+ return @header["Host"]
112
+ end
113
+
114
+ def origin
115
+ return @header["Origin"]
116
+ end
117
+
118
+ # Does closing handshake.
119
+ def close()
120
+ return if @closing_started
121
+ write("\xff\x00")
122
+ @socket.close() if !@server
123
+ @closing_started = true
124
+ end
125
+
126
+ def close_socket()
127
+ @socket.close()
128
+ end
129
+
130
+ private
131
+
132
+ NOISE_CHARS = ("\x21".."\x2f").to_a() + ("\x3a".."\x7e").to_a()
133
+
134
+ def read_header()
135
+ @header = {}
136
+ while line = gets()
137
+ line = line.chomp()
138
+ break if line.empty?
139
+ if !(line =~ /\A(\S+): (.*)\z/n)
140
+ raise(WebSocket::Error, "invalid request: #{line}")
141
+ end
142
+ @header[$1] = $2
143
+ end
144
+ if @header["Upgrade"] != "WebSocket"
145
+ raise(WebSocket::Error, "invalid Upgrade: " + @header["Upgrade"])
146
+ end
147
+ if @header["Connection"] != "Upgrade"
148
+ raise(WebSocket::Error, "invalid Connection: " + @header["Connection"])
149
+ end
150
+ end
151
+
152
+ def gets(rs = $/)
153
+ line = @socket.gets(rs)
154
+ $stderr.printf("recv> %p\n", line) if WebSocket.debug
155
+ return line
156
+ end
157
+
158
+ def read(num_bytes)
159
+ str = @socket.read(num_bytes)
160
+ $stderr.printf("recv> %p\n", str) if WebSocket.debug
161
+ return str
162
+ end
163
+
164
+ def write(data)
165
+ if WebSocket.debug
166
+ data.scan(/\G(.*?(\n|\z))/n) do
167
+ $stderr.printf("send> %p\n", $&) if !$&.empty?
168
+ end
169
+ end
170
+ @socket.write(data)
171
+ end
172
+
173
+ def flush()
174
+ @socket.flush()
175
+ end
176
+
177
+ def security_digest(key1, key2, key3)
178
+ bytes1 = websocket_key_to_bytes(key1)
179
+ bytes2 = websocket_key_to_bytes(key2)
180
+ return Digest::MD5.digest(bytes1 + bytes2 + key3)
181
+ end
182
+
183
+ def generate_key()
184
+ spaces = 1 + rand(12)
185
+ max = 0xffffffff / spaces
186
+ number = rand(max + 1)
187
+ key = (number * spaces).to_s()
188
+ (1 + rand(12)).times() do
189
+ char = NOISE_CHARS[rand(NOISE_CHARS.size)]
190
+ pos = rand(key.size + 1)
191
+ key[pos...pos] = char
192
+ end
193
+ spaces.times() do
194
+ pos = 1 + rand(key.size - 1)
195
+ key[pos...pos] = " "
196
+ end
197
+ return key
198
+ end
199
+
200
+ def generate_key3()
201
+ return [rand(0x100000000)].pack("N") + [rand(0x100000000)].pack("N")
202
+ end
203
+
204
+ def websocket_key_to_bytes(key)
205
+ num = key.gsub(/[^\d]/n, "").to_i() / key.scan(/ /).size
206
+ return [num].pack("N")
207
+ end
208
+
209
+ def force_encoding(str, encoding)
210
+ if str.respond_to?(:force_encoding)
211
+ return str.force_encoding(encoding)
212
+ else
213
+ return str
214
+ end
215
+ end
216
+
217
+ def ssl_handshake(socket)
218
+ ssl_context = OpenSSL::SSL::SSLContext.new()
219
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
220
+ ssl_socket.sync_close = true
221
+ ssl_socket.connect()
222
+ return ssl_socket
223
+ end
224
+ end # WebSocket
225
+ end # Rocket
@@ -0,0 +1,72 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rocket}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Araneo", "Chris Kowalik"]
12
+ s.date = %q{2010-11-03}
13
+ s.description = %q{
14
+ Rocket is a very fast and reliable web socket server built upon em-websockets library.
15
+ Rocket provides also JavaScript toolkit to serve up instructions to clients, and
16
+ ruby library which handles events triggering. This Project was strongly inspired
17
+ by awesome PusherApp.
18
+ }
19
+ s.email = %q{chris@nu7hat.ch}
20
+ s.extra_rdoc_files = [
21
+ "LICENSE",
22
+ "README.md"
23
+ ]
24
+ s.files = [
25
+ ".gitignore",
26
+ "LICENSE",
27
+ "README.md",
28
+ "Rakefile",
29
+ "bin/rocket",
30
+ "lib/rocket.rb",
31
+ "lib/rocket/channel.rb",
32
+ "lib/rocket/client.rb",
33
+ "lib/rocket/helpers.rb",
34
+ "lib/rocket/version.rb",
35
+ "lib/rocket/websocket.rb",
36
+ "rocket.gemspec",
37
+ "spec/helpers_spec.rb",
38
+ "spec/rocket_spec.rb",
39
+ "spec/spec_helper.rb"
40
+ ]
41
+ s.homepage = %q{http://github.com/araneo/rocket}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.7}
45
+ s.summary = %q{Event-oriented WebSockets server and toolkit.}
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<rocket-server>, ["= 0.0.1"])
53
+ s.add_runtime_dependency(%q<rocket-js>, ["= 0.0.1"])
54
+ s.add_runtime_dependency(%q<json>, ["~> 1.4"])
55
+ s.add_development_dependency(%q<rspec>, ["~> 2.0"])
56
+ s.add_development_dependency(%q<mocha>, ["~> 0.9"])
57
+ else
58
+ s.add_dependency(%q<rocket-server>, ["= 0.0.1"])
59
+ s.add_dependency(%q<rocket-js>, ["= 0.0.1"])
60
+ s.add_dependency(%q<json>, ["~> 1.4"])
61
+ s.add_dependency(%q<rspec>, ["~> 2.0"])
62
+ s.add_dependency(%q<mocha>, ["~> 0.9"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<rocket-server>, ["= 0.0.1"])
66
+ s.add_dependency(%q<rocket-js>, ["= 0.0.1"])
67
+ s.add_dependency(%q<json>, ["~> 1.4"])
68
+ s.add_dependency(%q<rspec>, ["~> 2.0"])
69
+ s.add_dependency(%q<mocha>, ["~> 0.9"])
70
+ end
71
+ end
72
+
@@ -0,0 +1,21 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+
3
+ class HelpersPoweredClass
4
+ include Rocket::Helpers
5
+ end
6
+
7
+ describe Rocket::Helpers do
8
+ subject do
9
+ HelpersPoweredClass.new
10
+ end
11
+
12
+ describe "#symbolize_keys" do
13
+ it "should return given object when it's not a Hash" do
14
+ subject.symbolize_keys(obj = Object.new).should == obj
15
+ end
16
+
17
+ it "should symbolize given hash keys" do
18
+ subject.symbolize_keys({"hello" => "world"}).should == {:hello => "world"}
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+
3
+ describe Rocket do
4
+ subject do
5
+ Rocket
6
+ end
7
+
8
+ it ".version should be valid" do
9
+ subject.version.should =~ /\d+(.\d+){1,2}.*/
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'mocha'
3
+ require 'rspec'
4
+ require 'rocket'
5
+
6
+ RSpec.configure do |config|
7
+ config.mock_with :mocha
8
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rocket
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Araneo
14
+ - Chris Kowalik
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-11-03 00:00:00 +01:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: rocket-server
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - "="
29
+ - !ruby/object:Gem::Version
30
+ hash: 29
31
+ segments:
32
+ - 0
33
+ - 0
34
+ - 1
35
+ version: 0.0.1
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rocket-js
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - "="
45
+ - !ruby/object:Gem::Version
46
+ hash: 29
47
+ segments:
48
+ - 0
49
+ - 0
50
+ - 1
51
+ version: 0.0.1
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ - !ruby/object:Gem::Dependency
55
+ name: json
56
+ prerelease: false
57
+ requirement: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ hash: 7
63
+ segments:
64
+ - 1
65
+ - 4
66
+ version: "1.4"
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 2
80
+ - 0
81
+ version: "2.0"
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: mocha
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ~>
91
+ - !ruby/object:Gem::Version
92
+ hash: 25
93
+ segments:
94
+ - 0
95
+ - 9
96
+ version: "0.9"
97
+ type: :development
98
+ version_requirements: *id005
99
+ description: |
100
+
101
+ Rocket is a very fast and reliable web socket server built upon em-websockets library.
102
+ Rocket provides also JavaScript toolkit to serve up instructions to clients, and
103
+ ruby library which handles events triggering. This Project was strongly inspired
104
+ by awesome PusherApp.
105
+
106
+ email: chris@nu7hat.ch
107
+ executables: []
108
+
109
+ extensions: []
110
+
111
+ extra_rdoc_files:
112
+ - LICENSE
113
+ - README.md
114
+ files:
115
+ - .gitignore
116
+ - LICENSE
117
+ - README.md
118
+ - Rakefile
119
+ - bin/rocket
120
+ - lib/rocket.rb
121
+ - lib/rocket/channel.rb
122
+ - lib/rocket/client.rb
123
+ - lib/rocket/helpers.rb
124
+ - lib/rocket/version.rb
125
+ - lib/rocket/websocket.rb
126
+ - rocket.gemspec
127
+ - spec/helpers_spec.rb
128
+ - spec/rocket_spec.rb
129
+ - spec/spec_helper.rb
130
+ has_rdoc: true
131
+ homepage: http://github.com/araneo/rocket
132
+ licenses: []
133
+
134
+ post_install_message:
135
+ rdoc_options:
136
+ - --charset=UTF-8
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ hash: 3
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ hash: 3
154
+ segments:
155
+ - 0
156
+ version: "0"
157
+ requirements: []
158
+
159
+ rubyforge_project:
160
+ rubygems_version: 1.3.7
161
+ signing_key:
162
+ specification_version: 3
163
+ summary: Event-oriented WebSockets server and toolkit.
164
+ test_files: []
165
+