iodine 0.1.21 → 0.2.0
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.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +3 -2
- data/.travis.yml +23 -2
- data/CHANGELOG.md +9 -2
- data/README.md +232 -179
- data/Rakefile +13 -1
- data/bin/config.ru +63 -0
- data/bin/console +6 -0
- data/bin/echo +42 -32
- data/bin/http-hello +62 -0
- data/bin/http-playground +124 -0
- data/bin/playground +62 -0
- data/bin/poc/Gemfile.lock +23 -0
- data/bin/poc/README.md +37 -0
- data/bin/poc/config.ru +66 -0
- data/bin/poc/gemfile +1 -0
- data/bin/poc/www/index.html +57 -0
- data/bin/raw-rbhttp +35 -0
- data/bin/raw_broadcast +66 -0
- data/bin/test_with_faye +40 -0
- data/bin/ws-broadcast +108 -0
- data/bin/ws-echo +108 -0
- data/exe/iodine +59 -0
- data/ext/iodine/base64.c +264 -0
- data/ext/iodine/base64.h +72 -0
- data/ext/iodine/bscrypt-common.h +109 -0
- data/ext/iodine/bscrypt.h +49 -0
- data/ext/iodine/extconf.rb +41 -0
- data/ext/iodine/hex.c +123 -0
- data/ext/iodine/hex.h +70 -0
- data/ext/iodine/http.c +200 -0
- data/ext/iodine/http.h +128 -0
- data/ext/iodine/http1.c +402 -0
- data/ext/iodine/http1.h +56 -0
- data/ext/iodine/http1_simple_parser.c +473 -0
- data/ext/iodine/http1_simple_parser.h +59 -0
- data/ext/iodine/http_request.h +128 -0
- data/ext/iodine/http_response.c +1606 -0
- data/ext/iodine/http_response.h +393 -0
- data/ext/iodine/http_response_http1.h +374 -0
- data/ext/iodine/iodine_core.c +641 -0
- data/ext/iodine/iodine_core.h +70 -0
- data/ext/iodine/iodine_http.c +615 -0
- data/ext/iodine/iodine_http.h +19 -0
- data/ext/iodine/iodine_websocket.c +430 -0
- data/ext/iodine/iodine_websocket.h +21 -0
- data/ext/iodine/libasync.c +552 -0
- data/ext/iodine/libasync.h +117 -0
- data/ext/iodine/libreact.c +347 -0
- data/ext/iodine/libreact.h +244 -0
- data/ext/iodine/libserver.c +912 -0
- data/ext/iodine/libserver.h +435 -0
- data/ext/iodine/libsock.c +950 -0
- data/ext/iodine/libsock.h +478 -0
- data/ext/iodine/misc.c +181 -0
- data/ext/iodine/misc.h +76 -0
- data/ext/iodine/random.c +193 -0
- data/ext/iodine/random.h +48 -0
- data/ext/iodine/rb-call.c +127 -0
- data/ext/iodine/rb-call.h +60 -0
- data/ext/iodine/rb-libasync.h +79 -0
- data/ext/iodine/rb-rack-io.c +389 -0
- data/ext/iodine/rb-rack-io.h +17 -0
- data/ext/iodine/rb-registry.c +213 -0
- data/ext/iodine/rb-registry.h +33 -0
- data/ext/iodine/sha1.c +359 -0
- data/ext/iodine/sha1.h +85 -0
- data/ext/iodine/sha2.c +825 -0
- data/ext/iodine/sha2.h +138 -0
- data/ext/iodine/siphash.c +136 -0
- data/ext/iodine/siphash.h +15 -0
- data/ext/iodine/spnlock.h +235 -0
- data/ext/iodine/websockets.c +696 -0
- data/ext/iodine/websockets.h +120 -0
- data/ext/iodine/xor-crypt.c +189 -0
- data/ext/iodine/xor-crypt.h +107 -0
- data/iodine.gemspec +25 -18
- data/lib/iodine.rb +57 -58
- data/lib/iodine/http.rb +0 -189
- data/lib/iodine/protocol.rb +36 -245
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +145 -2
- metadata +115 -37
- data/bin/core_http_test +0 -51
- data/bin/em playground +0 -56
- data/bin/hello_world +0 -75
- data/bin/setup +0 -7
- data/lib/iodine/client.rb +0 -5
- data/lib/iodine/core.rb +0 -102
- data/lib/iodine/core_init.rb +0 -143
- data/lib/iodine/http/hpack.rb +0 -553
- data/lib/iodine/http/http1.rb +0 -251
- data/lib/iodine/http/http2.rb +0 -507
- data/lib/iodine/http/rack_support.rb +0 -108
- data/lib/iodine/http/request.rb +0 -462
- data/lib/iodine/http/response.rb +0 -474
- data/lib/iodine/http/session.rb +0 -143
- data/lib/iodine/http/websocket_client.rb +0 -335
- data/lib/iodine/http/websocket_handler.rb +0 -101
- data/lib/iodine/http/websockets.rb +0 -336
- data/lib/iodine/io.rb +0 -56
- data/lib/iodine/logging.rb +0 -46
- data/lib/iodine/settings.rb +0 -158
- data/lib/iodine/ssl_connector.rb +0 -48
- data/lib/iodine/timers.rb +0 -95
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
+
require "rake/extensiontask"
|
3
4
|
|
4
5
|
Rake::TestTask.new(:test) do |t|
|
5
6
|
t.libs << "test"
|
@@ -7,4 +8,15 @@ Rake::TestTask.new(:test) do |t|
|
|
7
8
|
t.test_files = FileList['test/**/*_test.rb']
|
8
9
|
end
|
9
10
|
|
10
|
-
task :default => :test
|
11
|
+
task :default => [:compile, :test]
|
12
|
+
|
13
|
+
Rake::ExtensionTask.new "iodine" do |ext|
|
14
|
+
ext.lib_dir = "lib/iodine"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Rake::ExtensionTask.new "iodine_http" do |ext|
|
18
|
+
# ext.name = 'iodine_http'
|
19
|
+
# ext.lib_dir = "lib/iodine"
|
20
|
+
# ext.ext_dir = 'ext/iodine'
|
21
|
+
# ext.config_script = 'extconf-http.rb'
|
22
|
+
# end
|
data/bin/config.ru
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'rack/sendfile'
|
3
|
+
require 'rack/lint'
|
4
|
+
|
5
|
+
# There are a number of possible applications to run in this file,
|
6
|
+
# because I use it to test stuff.
|
7
|
+
#
|
8
|
+
# This value (app) sets which of the different applications will run.
|
9
|
+
#
|
10
|
+
# Valid values are "hello", "slow" (debugs env values), "simple"
|
11
|
+
app = 'hello'
|
12
|
+
# This is a simple Hello World Rack application, for benchmarking.
|
13
|
+
hello = proc do |_env|
|
14
|
+
[200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
15
|
+
'Content-Length'.freeze => '16'.freeze },
|
16
|
+
['Hello from Rack!'.freeze]]
|
17
|
+
end
|
18
|
+
|
19
|
+
slow = proc do |env|
|
20
|
+
out = "ENV:\n<br/>\n#{env.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n<br/>\n"}\n<br/>\n"
|
21
|
+
request = Rack::Request.new(env)
|
22
|
+
# Benchmark.bm do |bm|
|
23
|
+
# bm.report('Reading from env Hash to a string X 1000') { 1000.times { out = "ENV:\r\n#{env.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}\n" } }
|
24
|
+
# bm.report('Creating the Rack::Request (can\'t repeat)') { 1.times { request = Rack::Request.new(env) } }
|
25
|
+
# end
|
26
|
+
if request.path_info == '/source'.freeze
|
27
|
+
[200, { 'X-Sendfile' => File.expand_path(__FILE__) }, []]
|
28
|
+
else
|
29
|
+
out += "\n<br/>\nRequest Path: #{request.path_info}\n<br/>\nParams:\n<br/>\n#{request.params.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n<br/>\n"}\n<br/>\n" unless request.params.empty?
|
30
|
+
[200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
31
|
+
'Content-Length'.freeze => out.length.to_s },
|
32
|
+
[out]]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
simple = proc do |env|
|
37
|
+
request = Rack::Request.new(env)
|
38
|
+
if request.path_info == '/source'.freeze
|
39
|
+
[200, { 'X-Sendfile' => File.expand_path(__FILE__) }, []]
|
40
|
+
elsif request.path_info == '/file'.freeze
|
41
|
+
[200, { 'X-Header' => 'This was a Rack::Sendfile response' }, File.open(__FILE__)]
|
42
|
+
else
|
43
|
+
[200, { 'Content-Type'.freeze => 'text/html'.freeze,
|
44
|
+
'Content-Length'.freeze => request.path_info.length.to_s },
|
45
|
+
[request.path_info]]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
case app
|
50
|
+
when 'simple'
|
51
|
+
use Rack::Sendfile
|
52
|
+
run simple
|
53
|
+
when 'hello'
|
54
|
+
run hello
|
55
|
+
when 'slow'
|
56
|
+
use Rack::Lint
|
57
|
+
run slow
|
58
|
+
else
|
59
|
+
run hello
|
60
|
+
end
|
61
|
+
|
62
|
+
# ab -n 1000000 -c 2000 -k http://127.0.0.1:3000/
|
63
|
+
# wrk -c400 -d5 -t12 http://localhost:3000/
|
data/bin/console
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
# this will compile Iodine and start a Ruby console with the Iodine gem loaded.
|
4
|
+
|
5
|
+
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
6
|
+
puts `rake clean`
|
7
|
+
puts `rake compile`
|
8
|
+
|
3
9
|
require 'benchmark'
|
4
10
|
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__ )
|
5
11
|
require "bundler/setup"
|
data/bin/echo
CHANGED
@@ -1,36 +1,46 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
3
|
+
# this will compile Iodine and run an echo server.
|
4
|
+
|
5
|
+
# # test using:
|
6
|
+
# telnet localhost 3000
|
7
|
+
|
8
|
+
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
9
|
+
puts `rake clean`
|
10
|
+
puts `rake compile`
|
11
|
+
|
12
|
+
require 'benchmark'
|
13
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
14
|
+
require 'bundler/setup'
|
15
|
+
require 'iodine'
|
16
|
+
|
17
|
+
class EchoProtocol
|
18
|
+
@timeout = 10
|
19
|
+
|
20
|
+
def self.on_start
|
21
|
+
puts '* Echo service is now running.'
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_open
|
25
|
+
puts 'New connection'
|
26
|
+
end
|
27
|
+
|
28
|
+
def ping
|
29
|
+
write "-- are you there?\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
# `on_message` is an optional alternative to the `on_data` callback.
|
33
|
+
# `on_message` has a 1Kb buffer that recycles itself for memory optimization.
|
34
|
+
def on_message(buffer)
|
35
|
+
# writing will never block and will use a buffer written in C when needed.
|
36
|
+
write "Echo: #{buffer}"
|
37
|
+
puts buffer.dump
|
38
|
+
close if buffer =~ /^bye[\r\n]/i
|
39
|
+
end
|
33
40
|
end
|
34
41
|
|
35
|
-
|
36
|
-
Iodine.
|
42
|
+
# create the server object and setup any settings we might need.
|
43
|
+
Iodine.listen 3000, EchoProtocol
|
44
|
+
# server.threads = 10
|
45
|
+
# server.processes = 1
|
46
|
+
Iodine.start
|
data/bin/http-hello
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# this will compile Iodine and run an HTTP server "Hello World" example.
|
4
|
+
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
5
|
+
puts `rake clean`
|
6
|
+
puts `rake compile`
|
7
|
+
|
8
|
+
require 'benchmark'
|
9
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
10
|
+
require 'bundler/setup'
|
11
|
+
require 'iodine'
|
12
|
+
require 'rack'
|
13
|
+
|
14
|
+
# create the server object and setup any settings we might need.
|
15
|
+
Iodine::Rack
|
16
|
+
Iodine.threads ||= 16
|
17
|
+
Iodine.processes ||= 1 # 4
|
18
|
+
Iodine::Rack.public = '~/Documents/Scratch'
|
19
|
+
count = 2
|
20
|
+
Iodine::Rack.app = proc { |_env| [200, { 'Content-Length'.freeze => '12'.freeze }, ['He11o World!'.freeze]] }
|
21
|
+
puts Iodine::Rack.address
|
22
|
+
Iodine.start
|
23
|
+
|
24
|
+
# puts env.to_a.map { |pair| pair.join(': ') } .join("\n").to_s;
|
25
|
+
|
26
|
+
# puts "Press enter to start (#{Process.pid})"
|
27
|
+
# gets
|
28
|
+
|
29
|
+
###############
|
30
|
+
## for testing:
|
31
|
+
|
32
|
+
# def nag
|
33
|
+
# puts `ab -n 200000 -c 2000 -k http://127.0.0.1:3000/`
|
34
|
+
# sleep 2
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# nag while true
|
38
|
+
#
|
39
|
+
# def nag
|
40
|
+
# puts `wrk -c2000 -d10 -t4 http://localhost:3000/`
|
41
|
+
# sleep 3
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# nag while true
|
45
|
+
|
46
|
+
# ab -n 100000 -c 200 -k http://127.0.0.1:3000/
|
47
|
+
# ab -n 100000 -c 4000 -k http://127.0.0.1:3000/
|
48
|
+
# ab -n 1000000 -c 20000 -k http://127.0.0.1:3000/
|
49
|
+
# ~/ruby/wrk/wrk -c400 -d10 -t12 http://localhost:3000/
|
50
|
+
# wrk -c200 -d4 -t12 http://localhost:3000/
|
51
|
+
# RACK_ENV="production" rackup -p 3000 -s iodine
|
52
|
+
|
53
|
+
# thor --amount 5000 ws://localhost:3000/echo
|
54
|
+
# thor --amount 5000 ws://localhost:3000/broadcast
|
55
|
+
|
56
|
+
# ws = new WebSocket("ws://localhost:3000"); ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data);}; ws.onclose = function(e) {console.log("closed")}; ws.onopen = function(e) {ws.send("hi");};
|
57
|
+
# for(i = 0; i< 256; i++) {
|
58
|
+
# ws = new WebSocket("ws://localhost:3000");
|
59
|
+
# ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data); e.target.close(); };
|
60
|
+
# ws.onclose = function(e) {console.log("closed")};
|
61
|
+
# ws.onopen = function(e) {e.target.send("hi");};
|
62
|
+
# };
|
data/bin/http-playground
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# this is arbitrary code that will be executed after Iodine compiles. Used for ad-hok testing.
|
4
|
+
|
5
|
+
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
6
|
+
puts `rake clean`
|
7
|
+
puts `rake compile`
|
8
|
+
|
9
|
+
require 'benchmark'
|
10
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__)
|
11
|
+
require 'bundler/setup'
|
12
|
+
require 'iodine'
|
13
|
+
require 'rack'
|
14
|
+
|
15
|
+
class WSEcho
|
16
|
+
def self.call(env)
|
17
|
+
if env['HTTP_UPGRADE'.freeze] =~ /websocket/i
|
18
|
+
env['iodine.websocket'.freeze] = WSEcho
|
19
|
+
return [0, {}, []]
|
20
|
+
end
|
21
|
+
out = "ENV:\r\n#{env.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}"
|
22
|
+
request = Rack::Request.new(env)
|
23
|
+
out += "\nRequest Path: #{request.path_info}\nParams:\r\n#{request.params.to_a.map { |h| "#{h[0]}: #{h[1]}" } .join "\n"}" unless request.params.empty?
|
24
|
+
[200, { 'Content-Length' => out.length }, [out]]
|
25
|
+
end
|
26
|
+
|
27
|
+
# def on_open
|
28
|
+
# puts "We have a websocket connection"
|
29
|
+
# end
|
30
|
+
# def on_close
|
31
|
+
# puts "Bye Bye... only #{ws_count} left..."
|
32
|
+
# end
|
33
|
+
def on_shutdown
|
34
|
+
puts "I'm shutting down #{self}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def on_message(data)
|
38
|
+
# puts data
|
39
|
+
write data
|
40
|
+
data_cp = data.dup
|
41
|
+
# puts "broadcasting #{data_cp.bytesize} bytes"
|
42
|
+
# each {|h| h.echo data_cp }
|
43
|
+
end
|
44
|
+
|
45
|
+
def echo(data)
|
46
|
+
write "echo: #{data}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# create the server object and setup any settings we might need.
|
51
|
+
Iodine.threads ||= 4
|
52
|
+
Iodine.processes ||= 1
|
53
|
+
Iodine::Rack.public = '/Users/2Be/Documents/Scratch'
|
54
|
+
count = 2
|
55
|
+
Iodine::Rack.app = WSEcho
|
56
|
+
|
57
|
+
# server.on_http= Proc.new do |env|
|
58
|
+
# # [200, {"Content-Length".freeze => "12".freeze}, ["Hello World!".freeze]];
|
59
|
+
# if env["HTTP_UPGRADE".freeze] =~ /websocket/i.freeze
|
60
|
+
# env['iodine.websocket'.freeze] = WSEcho.new
|
61
|
+
# [0,{}, []]
|
62
|
+
# else
|
63
|
+
# req = Rack::Request.new env
|
64
|
+
# res = Rack::Response.new
|
65
|
+
# res.write "Hello World!".freeze
|
66
|
+
# res.to_a
|
67
|
+
# end
|
68
|
+
# end
|
69
|
+
|
70
|
+
server.on_start do
|
71
|
+
# server.run {puts "I'm running!"}
|
72
|
+
# server.run_after(5000) {puts "5 seconds have passed."}
|
73
|
+
server.run_every(1000) { puts "#{server.count} clients connected." }
|
74
|
+
# server.run_every(10000) do
|
75
|
+
# begin
|
76
|
+
# puts "making a system call"
|
77
|
+
# puts `ab -n 100000 -c 200 -k http://127.0.0.1:3000/`
|
78
|
+
# rescue => e
|
79
|
+
# l = Logger.new STDOUT
|
80
|
+
# l.error e
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
end
|
84
|
+
|
85
|
+
# server.on_start do
|
86
|
+
# server.run_every(1000) {puts "#{server.connection_count} clients connected."}
|
87
|
+
# end
|
88
|
+
|
89
|
+
puts "Press enter to start (#{Process.pid})"
|
90
|
+
# gets
|
91
|
+
|
92
|
+
server.start
|
93
|
+
|
94
|
+
# def nag
|
95
|
+
# puts `ab -n 200000 -c 2000 -k http://127.0.0.1:3000/`
|
96
|
+
# sleep 2
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# nag while true
|
100
|
+
#
|
101
|
+
# def nag
|
102
|
+
# puts `wrk -c2000 -d10 -t4 http://localhost:3000/`
|
103
|
+
# sleep 3
|
104
|
+
# end
|
105
|
+
#
|
106
|
+
# nag while true
|
107
|
+
|
108
|
+
# ab -n 100000 -c 200 -k http://127.0.0.1:3000/
|
109
|
+
# ab -n 100000 -c 4000 -k http://127.0.0.1:3000/
|
110
|
+
# ab -n 1000000 -c 20000 -k http://127.0.0.1:3000/
|
111
|
+
# ~/ruby/wrk/wrk -c400 -d10 -t12 http://localhost:3000/
|
112
|
+
# wrk -c200 -d4 -t12 http://localhost:3000/
|
113
|
+
# RACK_ENV="production" rackup -p 3000 -s iodine
|
114
|
+
|
115
|
+
# thor --amount 5000 ws://localhost:3000/echo
|
116
|
+
# thor --amount 5000 ws://localhost:3000/broadcast
|
117
|
+
|
118
|
+
# ws = new WebSocket("ws://localhost:3000"); ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data);}; ws.onclose = function(e) {console.log("closed")}; ws.onopen = function(e) {ws.send("hi");};
|
119
|
+
# for(i = 0; i< 256; i++) {
|
120
|
+
# ws = new WebSocket("ws://localhost:3000");
|
121
|
+
# ws.onmessage = function(e) {console.log("Got message!"); console.log(e.data); e.target.close(); };
|
122
|
+
# ws.onclose = function(e) {console.log("closed")};
|
123
|
+
# ws.onopen = function(e) {e.target.send("hi");};
|
124
|
+
# };
|
data/bin/playground
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# this is arbitrary code that will be executed after Iodine compiles. Used for ad-hok testing.
|
4
|
+
|
5
|
+
Dir.chdir(File.expand_path(File.join('..', '..'), __FILE__))
|
6
|
+
puts `rake clean`
|
7
|
+
puts `rake compile`
|
8
|
+
|
9
|
+
require 'benchmark'
|
10
|
+
$LOAD_PATH.unshift File.expand_path(File.join('..', '..', 'lib'), __FILE__ )
|
11
|
+
require "bundler/setup"
|
12
|
+
require "iodine"
|
13
|
+
|
14
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
15
|
+
# with your gem easier. You can also use a different console, if you like.
|
16
|
+
|
17
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
18
|
+
# require "pry"
|
19
|
+
# Pry.start
|
20
|
+
|
21
|
+
class ShoooProtocol
|
22
|
+
def on_message buffer
|
23
|
+
write "what do you mean - #{buffer.strip} ?!\n"
|
24
|
+
close if buffer =~ /^bye[\r\n]/i
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
class EchoProtocol
|
29
|
+
# `on_message` is an optional alternative to the `on_data` callback.
|
30
|
+
# `on_message` has a 1Kb buffer that recycles itself for memory optimization.
|
31
|
+
def on_message buffer
|
32
|
+
# writing will never block and will use a buffer written in C when needed.
|
33
|
+
write buffer
|
34
|
+
puts buffer.dump
|
35
|
+
# close will be performed only once all the data in the write buffer
|
36
|
+
# was sent. use `force_close` to close early.
|
37
|
+
close if buffer =~ /^bye[\r\n]/i
|
38
|
+
# upgrade ShoooProtocol
|
39
|
+
# # use buffer.dup to save the data from being recycled once we return.
|
40
|
+
# data = buffer.dup
|
41
|
+
# # run asynchronous tasks with ease
|
42
|
+
# run do
|
43
|
+
# sleep 1
|
44
|
+
# puts "Echoed data: #{data}"
|
45
|
+
# end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# create the server object and setup any settings we might need.
|
50
|
+
server = Iodine.new
|
51
|
+
server.threads = 10
|
52
|
+
server.processes = 1
|
53
|
+
server.busy_msg = "To many connections, try again later."
|
54
|
+
server.protocol = EchoProtocol
|
55
|
+
|
56
|
+
b = server.on_start do
|
57
|
+
server.run_after(1000) {puts "A seconds have passed?"}
|
58
|
+
server.run_every(1000) {puts "#{server.connection_count} clients connected."}
|
59
|
+
puts "Since we have 2 timers, we have #{server.connection_count} connections."
|
60
|
+
end
|
61
|
+
|
62
|
+
server.start
|
@@ -0,0 +1,23 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/boazsegev/iodine.git
|
3
|
+
revision: 8b57a5f2008b9c35f2cf589be7ed121823a84582
|
4
|
+
specs:
|
5
|
+
iodine (0.2.0)
|
6
|
+
rack
|
7
|
+
rake-compiler
|
8
|
+
|
9
|
+
GEM
|
10
|
+
specs:
|
11
|
+
rack (2.0.1)
|
12
|
+
rake (11.2.2)
|
13
|
+
rake-compiler (0.9.5)
|
14
|
+
rake
|
15
|
+
|
16
|
+
PLATFORMS
|
17
|
+
ruby
|
18
|
+
|
19
|
+
DEPENDENCIES
|
20
|
+
iodine!
|
21
|
+
|
22
|
+
BUNDLED WITH
|
23
|
+
1.12.5
|