eventmachine 是一个快速轻量的网络协议框架,有不少ruby应用基于它实现,如thin, ruby-amqp. eventmachine在不同os上自动选择最佳的底层网络通知机制,在linux上用epoll,freebsd上用kqueue.
eventmachine对网络事件进行封装,有事件发生时回调预设的handler module。
事件处理都需要放在EventMachine::run里,可以分server, client两种模式
1
2
3
4
5
6
7
8 | #server
EventMachine::run {
EventMachine::start_server "0.0.0.0", port, ServerHandler
}
#client
EventMachine::run {
EventMachine::connect remote_server, port, ClientHandler #client
}
|
在一个网络连接的生存周期中,可能发生的回调事件有:
- post_init handler对象创建后,注意client模式时,即使连接还未建立也会被调用
- connection_completed 主动连接远端服务器,连接建立时
- receive_data 有数据可读时, 在这里需要处理协议细节
- unbind 连接关闭,主动关闭,对方关闭或网络错误
在handler上可以使用send_data发送数据.
最简单的echo server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | #!/usr/bin/env ruby
require 'rubygems'
require 'eventmachine'
module EchoServer
def post_init
puts "-- someone connected to the echo server!"
end
def receive_data data
send_data ">>>you sent: #{data}"
close_connection if data =~ /quit/i
end
def unbind
puts "-- someone disconnected from the echo server!"
end
end
EventMachine::run {
EventMachine::start_server "127.0.0.1", 8081, EchoServer
}
|
一个简单的http client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | #!/usr/bin/env ruby
require 'rubygems'
require 'eventmachine'
module HttpClient
def post_init
puts "sending request to server"
send_data "GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n"
end
def receive_data data
puts "recv: #{data}"
end
def unbind
puts "connection closed"
EventMachine::stop
end
end
EventMachine::run {
EventMachine::connect "www.baidu.com", 80, HttpClient
}
|
连接失败的例子:
1
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 | #!/usr/bin/env ruby
require 'rubygems'
require 'eventmachine'
module Client
def connection_completed
puts "connected"
end
def post_init
puts "handler inited"
end
def receive_data data
puts "recv: #{data}"
end
def unbind
puts "connection closed"
EventMachine::stop
end
end
EventMachine::run {
EventMachine::connect "api.jquery.com", 8088, Client
} |