revent 0.5 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/example/as_r/ping/Document.as +1 -0
- data/example/as_r/{README → ping/README} +0 -0
- data/example/as_r/{client.fla → ping/client.fla} +0 -0
- data/example/as_r/ping/client.swf +0 -0
- data/example/as_r/ping/server.rb +26 -0
- data/example/r_r/chat/client.rb +44 -0
- data/example/r_r/chat/server.rb +38 -0
- data/example/r_r/ping/client.rb +46 -0
- data/example/r_r/ping/server.rb +18 -0
- data/lib/revent/Client.as +8 -37
- data/lib/revent/ClientEvent.as +18 -0
- data/lib/revent/as_r.rb +58 -100
- data/lib/revent/captcha.rb +12 -3
- data/lib/revent/r_r.rb +61 -107
- metadata +15 -10
- data/example/as_r/Document.as +0 -1
- data/example/as_r/client.swf +0 -0
- data/example/as_r/server.rb +0 -53
- data/example/r_r/client.rb +0 -46
- data/example/r_r/server.rb +0 -46
- data/lib/revent/InvokeEvent.as +0 -25
@@ -0,0 +1 @@
|
|
1
|
+
package {
|
File without changes
|
Binary file
|
Binary file
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'revent/as_r'
|
3
|
+
|
4
|
+
class Server
|
5
|
+
include Revent::ASRServer
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
start_server('localhost', 1943)
|
9
|
+
end
|
10
|
+
|
11
|
+
def on_connect(con)
|
12
|
+
puts "on_connect: #{con.remote_ip}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_unbind(con)
|
16
|
+
puts "on_unbind: #{con.remote_ip}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_message(con, message)
|
20
|
+
con.send_message(message)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
EventMachine::run do
|
25
|
+
Server.new
|
26
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'revent/r_r'
|
3
|
+
|
4
|
+
class Client
|
5
|
+
include Revent::RRClient
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
connect('localhost', 1943)
|
9
|
+
end
|
10
|
+
|
11
|
+
def send_message(message)
|
12
|
+
con.send_message(message)
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_connect
|
16
|
+
puts 'Entered'
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_unbind
|
20
|
+
puts 'Connection error'
|
21
|
+
exit(0)
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_message(message)
|
25
|
+
puts message
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
$client
|
30
|
+
t1 = Thread.new do
|
31
|
+
EventMachine::run do
|
32
|
+
$client = Client.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
t2 = Thread.new do
|
37
|
+
loop do
|
38
|
+
message = gets
|
39
|
+
$client.send_message(message)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
t1.join
|
43
|
+
t2.join
|
44
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'revent/r_r'
|
3
|
+
|
4
|
+
class Server
|
5
|
+
include Revent::RRServer
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
start_server('localhost', 1943)
|
9
|
+
end
|
10
|
+
|
11
|
+
def on_connect(con)
|
12
|
+
message = 'Someone entered'
|
13
|
+
puts message
|
14
|
+
cons.each do |c|
|
15
|
+
c.send_message(message)
|
16
|
+
end
|
17
|
+
con.send_message(message)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_unbind(con)
|
21
|
+
message = 'Someone quit'
|
22
|
+
puts message
|
23
|
+
cons.each do |c|
|
24
|
+
c.send_message(message)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_message(con, message)
|
29
|
+
puts message
|
30
|
+
cons.each do |c|
|
31
|
+
c.send_message(message)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
EventMachine::run do
|
37
|
+
Server.new
|
38
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'revent/r_r'
|
3
|
+
|
4
|
+
class Client
|
5
|
+
N = 10**5
|
6
|
+
|
7
|
+
include Revent::RRClient
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
# Make the message about 100 bytes
|
11
|
+
@data = ''
|
12
|
+
100.times { @data << rand(10).to_s }
|
13
|
+
|
14
|
+
connect('localhost', 1943)
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_connect
|
18
|
+
@now = Time.now
|
19
|
+
@count = 0
|
20
|
+
N.times do |i|
|
21
|
+
data1 = "#{@data}#{i}"
|
22
|
+
data2 = i
|
23
|
+
message = [data1, data2]
|
24
|
+
con.send_message(message)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_message(message)
|
29
|
+
data1, data2 = message
|
30
|
+
data1 =~ /#{@data}(.+)/
|
31
|
+
puts 'Error' if data2 != $1.to_i
|
32
|
+
puts message
|
33
|
+
|
34
|
+
@count += 1
|
35
|
+
if @count == N
|
36
|
+
dt = Time.now - @now
|
37
|
+
puts N
|
38
|
+
puts dt
|
39
|
+
puts N/dt
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
EventMachine::run do
|
45
|
+
Client.new
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'revent/r_r'
|
3
|
+
|
4
|
+
class Server
|
5
|
+
include Revent::RRServer
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
start_server('localhost', 1943)
|
9
|
+
end
|
10
|
+
|
11
|
+
def on_message(con, message)
|
12
|
+
con.send_message(message)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
EventMachine::run do
|
17
|
+
Server.new
|
18
|
+
end
|
data/lib/revent/Client.as
CHANGED
@@ -5,10 +5,6 @@
|
|
5
5
|
import flash.utils.ByteArray;
|
6
6
|
|
7
7
|
public class Client extends EventDispatcher {
|
8
|
-
private static const TYPE_INVOKE:int = 0;
|
9
|
-
private static const TYPE_RESULT:int = 1;
|
10
|
-
private static const TYPE_ERROR:int = 2;
|
11
|
-
|
12
8
|
private var _socket:Socket;
|
13
9
|
private var _bytes:ByteArray;
|
14
10
|
|
@@ -37,37 +33,27 @@
|
|
37
33
|
return _socket.connected;
|
38
34
|
}
|
39
35
|
|
40
|
-
public function
|
41
|
-
_socket.writeObject(
|
42
|
-
_socket.flush();
|
43
|
-
}
|
44
|
-
|
45
|
-
public function result(cmd:Object, value:Object):void {
|
46
|
-
_socket.writeObject([TYPE_RESULT, cmd, value]);
|
47
|
-
_socket.flush();
|
48
|
-
}
|
49
|
-
|
50
|
-
public function error(cmd:Object, value:Object):void {
|
51
|
-
_socket.writeObject([TYPE_ERROR, cmd, value]);
|
36
|
+
public function sendMessage(message:Object):void {
|
37
|
+
_socket.writeObject(message);
|
52
38
|
_socket.flush();
|
53
39
|
}
|
54
40
|
|
55
41
|
// ---------------------------------------------------------------------------
|
56
42
|
|
57
43
|
private function onConnect(event:Event):void {
|
58
|
-
dispatchEvent(new
|
44
|
+
dispatchEvent(new ClientEvent(ClientEvent.CONNECT, null));
|
59
45
|
}
|
60
46
|
|
61
47
|
private function onClose(event:Event):void {
|
62
|
-
dispatchEvent(new
|
48
|
+
dispatchEvent(new ClientEvent(ClientEvent.CLOSE, null));
|
63
49
|
}
|
64
50
|
|
65
51
|
private function onIOError(event:IOErrorEvent):void {
|
66
|
-
dispatchEvent(new
|
52
|
+
dispatchEvent(new ClientEvent(ClientEvent.IO_ERROR, null));
|
67
53
|
}
|
68
54
|
|
69
55
|
private function onSecurityError(event:SecurityErrorEvent):void {
|
70
|
-
dispatchEvent(new
|
56
|
+
dispatchEvent(new ClientEvent(ClientEvent.SECURITY_ERROR, null));
|
71
57
|
}
|
72
58
|
|
73
59
|
private function onData(event:ProgressEvent):void {
|
@@ -81,23 +67,8 @@
|
|
81
67
|
|
82
68
|
try {
|
83
69
|
while (true) {
|
84
|
-
var
|
85
|
-
var
|
86
|
-
var cmd:Object = o[1];
|
87
|
-
var value:Object = o[2];
|
88
|
-
|
89
|
-
var e:InvokeEvent;
|
90
|
-
switch (type) {
|
91
|
-
case TYPE_INVOKE:
|
92
|
-
e = new InvokeEvent(InvokeEvent.INVOKE, cmd, value);
|
93
|
-
break;
|
94
|
-
case TYPE_RESULT:
|
95
|
-
e = new InvokeEvent(InvokeEvent.RESULT, cmd, value);
|
96
|
-
break;
|
97
|
-
case TYPE_ERROR:
|
98
|
-
e = new InvokeEvent(InvokeEvent.ERROR, cmd, value);
|
99
|
-
break;
|
100
|
-
}
|
70
|
+
var message:Object = _bytes.readObject();
|
71
|
+
var e:ClientEvent = new ClientEvent(ClientEvent.MESSAGE, message);
|
101
72
|
dispatchEvent(e);
|
102
73
|
|
103
74
|
// Cleanup
|
@@ -0,0 +1,18 @@
|
|
1
|
+
package revent {
|
2
|
+
import flash.events.Event;
|
3
|
+
|
4
|
+
public class ClientEvent extends Event {
|
5
|
+
public static const CONNECT:String = "CONNECT"; // The connection has opened, communication is ready.
|
6
|
+
public static const CLOSE:String = "CLOSE"; // The connection has closed, do not do any communication.
|
7
|
+
public static const IO_ERROR:String = "IO_ERROR";
|
8
|
+
public static const SECURITY_ERROR:String = "SECURITY_ERROR";
|
9
|
+
public static const MESSAGE:String = "MESSAGE";
|
10
|
+
|
11
|
+
public var message:Object;
|
12
|
+
|
13
|
+
public function ClientEvent(type:String, message:Object):void {
|
14
|
+
this.message = message;
|
15
|
+
super(type);
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
data/lib/revent/as_r.rb
CHANGED
@@ -3,26 +3,25 @@ require 'eventmachine'
|
|
3
3
|
require 'zlib'
|
4
4
|
require 'logger'
|
5
5
|
|
6
|
-
|
7
|
-
require "#{
|
6
|
+
dir = File.dirname(__FILE__)
|
7
|
+
require "#{dir}/synchronize"
|
8
|
+
require "#{dir}/amf3/amf3"
|
8
9
|
|
9
10
|
# AS clients are not reliable. For security, we close the connection immediately
|
10
11
|
# if there is any error.
|
11
12
|
module Revent
|
12
13
|
module ASRCon
|
13
|
-
#
|
14
|
-
|
14
|
+
# Sent by flash player
|
15
|
+
POLICY_REQUEST = "<policy-file-request/>\0"
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
TYPE_ERROR = 2
|
17
|
+
# The place to store something associated with this connection
|
18
|
+
attr_accessor :session
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def user=(server)
|
21
|
+
@user = server
|
22
|
+
end
|
23
23
|
|
24
24
|
def post_init
|
25
|
-
@connected = true
|
26
25
|
@data = ''
|
27
26
|
@dec = RubyAMF::IO::AMFDeserializer.new
|
28
27
|
@enc = RubyAMF::IO::AMFSerializer.new
|
@@ -30,13 +29,13 @@ module Revent
|
|
30
29
|
|
31
30
|
def receive_data(data)
|
32
31
|
@data << data
|
33
|
-
if @data ==
|
34
|
-
send_data(@
|
32
|
+
if @data == POLICY_REQUEST
|
33
|
+
send_data(@user.policy + "\0")
|
35
34
|
close_connection_after_writing
|
36
35
|
return
|
37
36
|
end
|
38
37
|
|
39
|
-
if @data.size > @
|
38
|
+
if @data.size > @user.max_data_size
|
40
39
|
close_connection
|
41
40
|
return
|
42
41
|
end
|
@@ -44,60 +43,49 @@ module Revent
|
|
44
43
|
while true
|
45
44
|
@dec.reset
|
46
45
|
@dec.stream = @data
|
47
|
-
|
48
|
-
break if
|
46
|
+
message = @dec.read_amf3
|
47
|
+
break if message.nil?
|
49
48
|
|
50
|
-
|
49
|
+
on_message(message)
|
51
50
|
|
52
51
|
last_size = @data.size
|
53
52
|
@data.slice!(0, @dec.stream_position)
|
54
53
|
break if last_size == @dec.stream_position
|
55
54
|
end
|
56
55
|
rescue
|
57
|
-
@
|
58
|
-
@
|
59
|
-
close_connection
|
60
|
-
end
|
61
|
-
|
62
|
-
def process(o)
|
63
|
-
type = o[0]
|
64
|
-
cmd = o[1]
|
65
|
-
value = o[2]
|
66
|
-
|
67
|
-
case type
|
68
|
-
when TYPE_INVOKE
|
69
|
-
@me.on_invoke(self, cmd, value)
|
70
|
-
when TYPE_RESULT
|
71
|
-
@me.on_result(self, cmd, value)
|
72
|
-
when TYPE_ERROR
|
73
|
-
@me.on_error(self, cmd, value)
|
74
|
-
end
|
75
|
-
rescue
|
76
|
-
@me.logger.error($!)
|
77
|
-
@me.logger.error($!.backtrace.join("\n"))
|
56
|
+
@user.logger.error($!)
|
57
|
+
@user.logger.error($!.backtrace.join("\n"))
|
78
58
|
close_connection
|
79
59
|
end
|
80
60
|
|
81
61
|
def unbind
|
82
|
-
@
|
83
|
-
@
|
84
|
-
@me.on_close(self)
|
62
|
+
@user.cons.synchronize { @user.cons.delete(self) }
|
63
|
+
@user.on_unbind(self)
|
85
64
|
end
|
86
65
|
|
87
|
-
|
66
|
+
# --------------------------------------------------------------------------
|
88
67
|
|
89
|
-
def
|
68
|
+
def send_message(message, close_connection_after_writing = false)
|
69
|
+
# Send AMF3 data
|
90
70
|
@enc.reset
|
91
|
-
@enc.write_amf3(
|
71
|
+
@enc.write_amf3(message)
|
92
72
|
send_data(@enc.stream)
|
93
73
|
@enc.reset
|
74
|
+
|
75
|
+
self.close_connection_after_writing if close_connection_after_writing
|
76
|
+
rescue
|
77
|
+
@user.logger.error($!)
|
78
|
+
@user.logger.error($!.backtrace.join("\n"))
|
94
79
|
end
|
95
80
|
|
96
|
-
def
|
97
|
-
@
|
81
|
+
def on_message(message)
|
82
|
+
@user.on_message(self, message)
|
83
|
+
rescue
|
84
|
+
@user.logger.error($!)
|
85
|
+
@user.logger.error($!.backtrace.join("\n"))
|
86
|
+
close_connection
|
98
87
|
end
|
99
88
|
|
100
|
-
# IP of the container.
|
101
89
|
def remote_ip
|
102
90
|
peername = get_peername
|
103
91
|
return @last_ip if peername.nil?
|
@@ -107,30 +95,6 @@ module Revent
|
|
107
95
|
@last_ip = a.join('.')
|
108
96
|
end
|
109
97
|
|
110
|
-
def invoke(cmd, value, close_connection_after_writing = false)
|
111
|
-
send_amf3_data([TYPE_INVOKE, cmd, value])
|
112
|
-
self.close_connection_after_writing if close_connection_after_writing
|
113
|
-
rescue
|
114
|
-
@me.logger.error($!)
|
115
|
-
@me.logger.error($!.backtrace.join("\n"))
|
116
|
-
end
|
117
|
-
|
118
|
-
def result(cmd, value, close_connection_after_writing = false)
|
119
|
-
send_amf3_data([TYPE_RESULT, cmd, value])
|
120
|
-
self.close_connection_after_writing if close_connection_after_writing
|
121
|
-
rescue
|
122
|
-
@me.logger.error($!)
|
123
|
-
@me.logger.error($!.backtrace.join("\n"))
|
124
|
-
end
|
125
|
-
|
126
|
-
def error(cmd, value, close_connection_after_writing = false)
|
127
|
-
send_amf3_data([TYPE_ERROR, cmd, value])
|
128
|
-
self.close_connection_after_writing if close_connection_after_writing
|
129
|
-
rescue
|
130
|
-
@me.logger.error($!)
|
131
|
-
@me.logger.error($!.backtrace.join("\n"))
|
132
|
-
end
|
133
|
-
|
134
98
|
def compress(value)
|
135
99
|
@enc.reset
|
136
100
|
@enc.write_amf3(value)
|
@@ -141,18 +105,29 @@ module Revent
|
|
141
105
|
end
|
142
106
|
end
|
143
107
|
|
144
|
-
#
|
108
|
+
# ----------------------------------------------------------------------------
|
109
|
+
|
110
|
+
# To make your class a server, just include Revent::ASRServer in it.
|
111
|
+
#
|
112
|
+
# The server has the following methods:
|
113
|
+
# * start_server
|
114
|
+
# * on_connect
|
115
|
+
# * on_unbind
|
116
|
+
# * on_message
|
117
|
+
#
|
118
|
+
# For more control, it uses "cons" directly.
|
145
119
|
module ASRServer
|
146
120
|
# For security check, normally command cannot be too long
|
147
|
-
|
121
|
+
DEFAULT_MAX_DATA_SIZE = 1024
|
148
122
|
|
149
|
-
attr_accessor :logger, :
|
123
|
+
attr_accessor :logger, :max_data_size, :policy
|
124
|
+
attr_reader :cons
|
150
125
|
|
151
|
-
# Set logger,
|
126
|
+
# Set logger, max_data_size, policy if you don't want the default values
|
152
127
|
# before calling this method.
|
153
128
|
def start_server(host, port)
|
154
129
|
@logger = Logger.new(STDOUT) if @logger.nil?
|
155
|
-
@
|
130
|
+
@max_data_size = DEFAULT_MAX_DATA_SIZE if @max_data_size.nil?
|
156
131
|
if @policy.nil?
|
157
132
|
@policy = %Q{
|
158
133
|
<cross-domain-policy>
|
@@ -161,39 +136,22 @@ module Revent
|
|
161
136
|
}
|
162
137
|
end
|
163
138
|
|
164
|
-
@
|
165
|
-
@revent_cons_mutex = Mutex.new
|
139
|
+
@cons = []
|
166
140
|
EventMachine::start_server(host, port, ASRCon) do |con|
|
167
|
-
|
168
|
-
|
169
|
-
con.
|
141
|
+
# con is an instance of a class that has included ASRCon
|
142
|
+
@cons.synchronize { @cons << con }
|
143
|
+
con.user = self
|
170
144
|
on_connect(con)
|
171
145
|
end
|
172
146
|
end
|
173
147
|
|
174
|
-
|
175
|
-
# if it is an instance of Revent::RRClient.
|
176
|
-
# ----------------------------------------------------------------------------
|
177
|
-
|
178
|
-
def clients
|
179
|
-
@revent_cons
|
180
|
-
end
|
181
|
-
|
182
|
-
# ----------------------------------------------------------------------------
|
183
|
-
|
184
|
-
def on_connect(client)
|
185
|
-
end
|
186
|
-
|
187
|
-
def on_close(client)
|
188
|
-
end
|
189
|
-
|
190
|
-
def on_invoke(client, cmd, value)
|
148
|
+
def on_connect(con)
|
191
149
|
end
|
192
150
|
|
193
|
-
def
|
151
|
+
def on_unbind(con)
|
194
152
|
end
|
195
153
|
|
196
|
-
def
|
154
|
+
def on_message(con, message)
|
197
155
|
end
|
198
156
|
end
|
199
157
|
end
|
data/lib/revent/captcha.rb
CHANGED
@@ -4,6 +4,15 @@ require 'RMagick'
|
|
4
4
|
|
5
5
|
module Revent
|
6
6
|
class Captcha
|
7
|
+
attr_reader :encrypted_code_with_timestamp, :img
|
8
|
+
|
9
|
+
def initialize(encrypted_code_with_timestamp, img)
|
10
|
+
@encrypted_code_with_timestamp = encrypted_code_with_timestamp
|
11
|
+
@img = img
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class CaptchaFactory
|
7
16
|
include Magick
|
8
17
|
|
9
18
|
JIGGLE = 15
|
@@ -18,10 +27,10 @@ module Revent
|
|
18
27
|
|
19
28
|
# Returns [encrypted_code_with_timestamp, img].
|
20
29
|
def new
|
21
|
-
code, img =
|
30
|
+
code, img = real_new
|
22
31
|
code_with_timestamp = code + Time.now.to_i.to_s
|
23
32
|
encrypted_code_with_timestamp = @b.encrypt_string(code_with_timestamp)
|
24
|
-
|
33
|
+
Captcha.new(encrypted_code_with_timestamp, img)
|
25
34
|
end
|
26
35
|
|
27
36
|
# Returns true if the code matches and within the valid period.
|
@@ -36,7 +45,7 @@ module Revent
|
|
36
45
|
|
37
46
|
# Returns [code (a string of A-Z), img]
|
38
47
|
VOCA = ('A'..'Z').to_a.freeze
|
39
|
-
def
|
48
|
+
def real_new
|
40
49
|
code_array = []
|
41
50
|
voca_length = VOCA.length
|
42
51
|
1.upto(@length) { code_array << VOCA[rand(voca_length)] }
|
data/lib/revent/r_r.rb
CHANGED
@@ -7,13 +7,13 @@ require "#{File.dirname(__FILE__)}/synchronize"
|
|
7
7
|
module Revent
|
8
8
|
# Included by both Revent::RRServer and Revent::RRClient.
|
9
9
|
module RRCon
|
10
|
-
|
11
|
-
|
12
|
-
TYPE_ERROR = 2
|
10
|
+
# The place to store something associated with this connection
|
11
|
+
attr_accessor :session
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def user=(server_or_client)
|
14
|
+
@user_is_server = server_or_client.respond_to?(:start_server)
|
15
|
+
@user = server_or_client
|
16
|
+
end
|
17
17
|
|
18
18
|
def post_init
|
19
19
|
@connected = true
|
@@ -24,159 +24,113 @@ module Revent
|
|
24
24
|
@data << data
|
25
25
|
while true
|
26
26
|
io = StringIO.new(@data)
|
27
|
-
|
27
|
+
message = Marshal.load(io)
|
28
28
|
@data.slice!(0, io.pos)
|
29
|
-
|
29
|
+
on_message(message)
|
30
30
|
end
|
31
31
|
rescue
|
32
32
|
end
|
33
33
|
|
34
|
-
def process(o)
|
35
|
-
type = o[0]
|
36
|
-
cmd = o[1]
|
37
|
-
value = o[2]
|
38
|
-
|
39
|
-
case type
|
40
|
-
when TYPE_INVOKE
|
41
|
-
value = @cons.nil? ? @me.on_invoke(cmd, value) : @me.on_invoke(self, cmd, value)
|
42
|
-
o = [TYPE_RESULT, cmd, value]
|
43
|
-
send_data(Marshal.dump(o))
|
44
|
-
when TYPE_RESULT
|
45
|
-
@cons.nil? ? @me.on_result(cmd, value) : @me.on_result(self, cmd, value)
|
46
|
-
when TYPE_ERROR
|
47
|
-
@cons.nil? ? @me.on_error(cmd, value) : @me.on_error(self, cmd, value)
|
48
|
-
end
|
49
|
-
rescue => e
|
50
|
-
o = [TYPE_ERROR, cmd, e]
|
51
|
-
send_data(Marshal.dump(o))
|
52
|
-
end
|
53
|
-
|
54
34
|
def unbind
|
55
|
-
@
|
56
|
-
|
57
|
-
@
|
35
|
+
if @user_is_server
|
36
|
+
@user.cons.synchronize { @user.cons.delete(self) }
|
37
|
+
@user.on_unbind(self)
|
58
38
|
else
|
59
|
-
@
|
60
|
-
@cons.synchronize { @cons.delete(self) }
|
39
|
+
@user.on_unbind
|
61
40
|
end
|
62
41
|
end
|
63
42
|
|
64
43
|
# --------------------------------------------------------------------------
|
65
44
|
|
66
|
-
def
|
67
|
-
|
45
|
+
def send_message(message)
|
46
|
+
send_data(Marshal.dump(message))
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_message(message)
|
50
|
+
@user.synchronize do
|
51
|
+
if @user_is_server
|
52
|
+
@user.on_message(self, message)
|
53
|
+
else
|
54
|
+
@user.on_message(message)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
rescue
|
68
58
|
end
|
69
59
|
|
70
|
-
# IP of the container.
|
71
60
|
def remote_ip
|
72
61
|
peername = get_peername
|
73
62
|
return @last_ip if peername.nil?
|
74
63
|
|
75
|
-
a = get_peername[2, 6].unpack(
|
64
|
+
a = get_peername[2, 6].unpack('nC4')
|
76
65
|
a.delete_at(0)
|
77
66
|
@last_ip = a.join('.')
|
78
67
|
end
|
79
|
-
|
80
|
-
def invoke(cmd, value)
|
81
|
-
o = [TYPE_INVOKE, cmd, value]
|
82
|
-
send_data(Marshal.dump(o))
|
83
|
-
end
|
84
68
|
end
|
85
69
|
|
70
|
+
# ----------------------------------------------------------------------------
|
86
71
|
|
87
72
|
# To make your class a server, just include Revent::RRServer in it.
|
73
|
+
#
|
74
|
+
# The server has the following methods:
|
75
|
+
# * start_server
|
76
|
+
# * on_connect
|
77
|
+
# * on_unbind
|
78
|
+
# * on_message
|
79
|
+
#
|
80
|
+
# For more control, it uses "cons" directly.
|
88
81
|
module RRServer
|
82
|
+
attr_reader :cons
|
83
|
+
|
89
84
|
def start_server(host, port)
|
90
|
-
@
|
85
|
+
@cons = []
|
91
86
|
EventMachine::start_server(host, port, RRCon) do |con|
|
92
|
-
|
93
|
-
con
|
94
|
-
|
87
|
+
con.user = self
|
88
|
+
# con is an instance of a class that has included RRCon
|
89
|
+
@cons.synchronize { @cons << con }
|
95
90
|
on_connect(con)
|
96
91
|
end
|
97
92
|
end
|
98
93
|
|
99
|
-
|
100
|
-
# if it is an instance of Revent::RRClient.
|
101
|
-
# ----------------------------------------------------------------------------
|
102
|
-
|
103
|
-
def clients
|
104
|
-
@revent_cons
|
105
|
-
end
|
106
|
-
|
107
|
-
# ----------------------------------------------------------------------------
|
108
|
-
|
109
|
-
def on_connect(client)
|
110
|
-
end
|
111
|
-
|
112
|
-
def on_close(client)
|
113
|
-
end
|
114
|
-
|
115
|
-
def on_invoke(client, cmd, value)
|
94
|
+
def on_connect(con)
|
116
95
|
end
|
117
96
|
|
118
|
-
def
|
97
|
+
def on_unbind(con)
|
119
98
|
end
|
120
99
|
|
121
|
-
def
|
100
|
+
def on_message(con, message)
|
122
101
|
end
|
123
102
|
end
|
124
103
|
|
104
|
+
# ----------------------------------------------------------------------------
|
105
|
+
|
125
106
|
# To make your class a client, just include Revent::RRClient in it.
|
107
|
+
#
|
108
|
+
# The client has the following methods:
|
109
|
+
# * connect
|
110
|
+
# * on_connect
|
111
|
+
# * on_unbind
|
112
|
+
# * on_message
|
113
|
+
#
|
114
|
+
# For more control, it uses "con" directly.
|
126
115
|
module RRClient
|
116
|
+
attr_reader :con
|
117
|
+
|
127
118
|
def connect(host, port)
|
128
119
|
EventMachine::connect(host, port, RRCon) do |con|
|
129
|
-
|
130
|
-
con.
|
120
|
+
# con is an instance of a class that has included RRCon
|
121
|
+
con.user = self
|
122
|
+
@con = con
|
131
123
|
on_connect
|
132
124
|
end
|
133
125
|
end
|
134
126
|
|
135
|
-
# Utilities ------------------------------------------------------------------
|
136
|
-
|
137
|
-
def connected?
|
138
|
-
@revent_con.nil? ? false : @revent_con.connected?
|
139
|
-
end
|
140
|
-
|
141
|
-
def session
|
142
|
-
@revent_con.session if connected?
|
143
|
-
end
|
144
|
-
|
145
|
-
def session=(value)
|
146
|
-
@revent_con.session = value if connected?
|
147
|
-
end
|
148
|
-
|
149
|
-
def remote_ip
|
150
|
-
@revent_con.remote_ip if connected?
|
151
|
-
end
|
152
|
-
|
153
|
-
def invoke(cmd, value)
|
154
|
-
@revent_con.invoke(cmd, value) if connected?
|
155
|
-
end
|
156
|
-
|
157
|
-
def close_connection
|
158
|
-
@revent_con.close_connection if connected?
|
159
|
-
end
|
160
|
-
|
161
|
-
def close_connection_after_writing
|
162
|
-
@revent_con.close_connection_after_writing if connected?
|
163
|
-
end
|
164
|
-
|
165
|
-
# ----------------------------------------------------------------------------
|
166
|
-
|
167
127
|
def on_connect
|
168
128
|
end
|
169
129
|
|
170
|
-
def
|
171
|
-
end
|
172
|
-
|
173
|
-
def on_invoke(cmd, value)
|
174
|
-
end
|
175
|
-
|
176
|
-
def on_result(cmd, value)
|
130
|
+
def on_unbind
|
177
131
|
end
|
178
132
|
|
179
|
-
def
|
133
|
+
def on_message(message)
|
180
134
|
end
|
181
135
|
end
|
182
136
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: revent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.6"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ngoc DAO Thanh
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-10-31 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -43,14 +43,19 @@ extra_rdoc_files: []
|
|
43
43
|
files:
|
44
44
|
- example
|
45
45
|
- example/as_r
|
46
|
-
- example/as_r/
|
47
|
-
- example/as_r/client.
|
48
|
-
- example/as_r/
|
49
|
-
- example/as_r/
|
50
|
-
- example/as_r/
|
46
|
+
- example/as_r/ping
|
47
|
+
- example/as_r/ping/client.fla
|
48
|
+
- example/as_r/ping/client.swf
|
49
|
+
- example/as_r/ping/Document.as
|
50
|
+
- example/as_r/ping/README
|
51
|
+
- example/as_r/ping/server.rb
|
51
52
|
- example/r_r
|
52
|
-
- example/r_r/
|
53
|
-
- example/r_r/
|
53
|
+
- example/r_r/chat
|
54
|
+
- example/r_r/chat/client.rb
|
55
|
+
- example/r_r/chat/server.rb
|
56
|
+
- example/r_r/ping
|
57
|
+
- example/r_r/ping/client.rb
|
58
|
+
- example/r_r/ping/server.rb
|
54
59
|
- INSTALL
|
55
60
|
- lib
|
56
61
|
- lib/revent
|
@@ -74,7 +79,7 @@ files:
|
|
74
79
|
- lib/revent/as_r.rb
|
75
80
|
- lib/revent/captcha.rb
|
76
81
|
- lib/revent/Client.as
|
77
|
-
- lib/revent/
|
82
|
+
- lib/revent/ClientEvent.as
|
78
83
|
- lib/revent/r_r.rb
|
79
84
|
- lib/revent/synchronize.rb
|
80
85
|
- README
|
data/example/as_r/Document.as
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
package {
|
data/example/as_r/client.swf
DELETED
Binary file
|
data/example/as_r/server.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'revent/as_r'
|
3
|
-
|
4
|
-
HOST = 'localhost'
|
5
|
-
PORT = 1935
|
6
|
-
|
7
|
-
class Server
|
8
|
-
include Revent::ASRServer
|
9
|
-
|
10
|
-
CMD_TEST_BYTE_ARRAY = 0
|
11
|
-
|
12
|
-
def initialize(host, port)
|
13
|
-
start_server(host, port)
|
14
|
-
end
|
15
|
-
|
16
|
-
def on_connect(client)
|
17
|
-
puts "on_connect: ", client.remote_ip
|
18
|
-
end
|
19
|
-
|
20
|
-
def on_close(client)
|
21
|
-
puts "on_close:", client.remote_ip
|
22
|
-
end
|
23
|
-
|
24
|
-
def on_invoke(client, cmd, value)
|
25
|
-
puts "on_invoke: ", cmd, value
|
26
|
-
if cmd == CMD_TEST_BYTE_ARRAY
|
27
|
-
test_byte_array(client, value)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def on_result(client, cmd, value)
|
32
|
-
puts "on_result: ", client.remote_ip, cmd, result
|
33
|
-
end
|
34
|
-
|
35
|
-
def on_error(client, cmd, value)
|
36
|
-
puts "on_error: ", client.remote_ip, cmd, error
|
37
|
-
end
|
38
|
-
|
39
|
-
# ----------------------------------------------------------------------------
|
40
|
-
|
41
|
-
def test_byte_array(client, length)
|
42
|
-
bytes = ''
|
43
|
-
length.times do
|
44
|
-
bytes << rand(256)
|
45
|
-
end
|
46
|
-
byte_array = RubyAMF::IO::ByteArray.new(bytes)
|
47
|
-
client.result(CMD_TEST_BYTE_ARRAY, byte_array)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
EventMachine::run do
|
52
|
-
Server.new(HOST, PORT)
|
53
|
-
end
|
data/example/r_r/client.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'revent/r_r'
|
3
|
-
|
4
|
-
class Client
|
5
|
-
include Revent::RRClient
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@data_prefix = ''
|
9
|
-
50.times { |i| @data_prefix << i.to_s }
|
10
|
-
|
11
|
-
connect('localhost', 1943)
|
12
|
-
end
|
13
|
-
|
14
|
-
N = 10**4
|
15
|
-
|
16
|
-
def on_connect
|
17
|
-
@now = Time.now
|
18
|
-
@count = 0
|
19
|
-
N.times do |i|
|
20
|
-
invoke("#{@data_prefix}#{i}", i)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def on_invoke(cmd, value)
|
25
|
-
cmd =~ /#{@data_prefix}(.+)/
|
26
|
-
puts 'Error at on_invoke' if value != $1.to_i
|
27
|
-
value
|
28
|
-
end
|
29
|
-
|
30
|
-
def on_result(cmd, value)
|
31
|
-
cmd =~ /#{@data_prefix}(.+)/
|
32
|
-
puts 'Error at on_result' if value != $1.to_i
|
33
|
-
|
34
|
-
@count += 1
|
35
|
-
if @count == N
|
36
|
-
dt = Time.now - @now
|
37
|
-
puts N
|
38
|
-
puts dt
|
39
|
-
puts N/dt
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
EventMachine::run do
|
45
|
-
Client.new
|
46
|
-
end
|
data/example/r_r/server.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'revent/r_r'
|
3
|
-
|
4
|
-
class Server
|
5
|
-
include Revent::RRServer
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@data_prefix = ''
|
9
|
-
50.times { |i| @data_prefix << i.to_s }
|
10
|
-
|
11
|
-
start_server('localhost', 1943)
|
12
|
-
end
|
13
|
-
|
14
|
-
N = 10**4
|
15
|
-
|
16
|
-
def on_connect(con)
|
17
|
-
@count = 0
|
18
|
-
@now = Time.now
|
19
|
-
N.times do |i|
|
20
|
-
con.invoke("#{@data_prefix}#{i}", i)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def on_invoke(con, cmd, value)
|
25
|
-
cmd =~ /#{@data_prefix}(.+)/
|
26
|
-
puts 'Error at on_invoke' if value != $1.to_i
|
27
|
-
value
|
28
|
-
end
|
29
|
-
|
30
|
-
def on_result(con, cmd, value)
|
31
|
-
cmd =~ /#{@data_prefix}(.+)/
|
32
|
-
puts 'Error at on_result' if value != $1.to_i
|
33
|
-
|
34
|
-
@count += 1
|
35
|
-
if @count == N
|
36
|
-
dt = Time.now - @now
|
37
|
-
puts N
|
38
|
-
puts dt
|
39
|
-
puts N/dt
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
EventMachine::run do
|
45
|
-
Server.new
|
46
|
-
end
|
data/lib/revent/InvokeEvent.as
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
package revent {
|
2
|
-
import flash.events.Event;
|
3
|
-
|
4
|
-
public class InvokeEvent extends Event {
|
5
|
-
// The connection has opened, communication is ready.
|
6
|
-
public static const CONNECT:String = "CONNECT";
|
7
|
-
// The connection has closed, do not do any communication.
|
8
|
-
public static const CLOSE:String = "CLOSE";
|
9
|
-
public static const IO_ERROR:String = "IO_ERROR";
|
10
|
-
public static const SECURITY_ERROR:String = "SECURITY_ERROR";
|
11
|
-
|
12
|
-
public static const INVOKE:String = "INVOKE";
|
13
|
-
public static const RESULT:String = "RESULT";
|
14
|
-
public static const ERROR:String = "ERROR";
|
15
|
-
|
16
|
-
public var cmd:Object;
|
17
|
-
public var value:Object;
|
18
|
-
|
19
|
-
public function InvokeEvent(type:String, cmd:Object, value:Object):void {
|
20
|
-
this.cmd = cmd;
|
21
|
-
this.value = value;
|
22
|
-
super(type);
|
23
|
-
}
|
24
|
-
}
|
25
|
-
}
|