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