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\n Host: www.baidu.com \r\n Connection: 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
}