在了解here给出的基本“异步/ io”示例时,我需要一些帮助:
require 'async/io'
def echo_server(endpoint)
Async::Reactor.run do |task|
# This is a synchronous block within the current task:
endpoint.accept do |client|
# This is an asynchronous block within the current reactor:
data = client.read(512)
# This produces out-of-order responses.
task.sleep(rand * 0.01)
client.write(data.reverse)
end
end
end
def echo_client(endpoint, data)
Async::Reactor.run do |task|
endpoint.connect do |peer|
result = peer.write(data)
message = peer.read(512)
puts "Sent #{data}, got response: #{message}"
end
end
end
Async::Reactor.run do
endpoint = Async::IO::Endpoint.tcp('0.0.0.0', 9000)
server = echo_server(endpoint)
5.times.collect do |i|
echo_client(endpoint, "Hello World #{i}")
end.each(&:wait)
server.stop
end
反应堆模式(正确的话,如果错误的话,请改正)基本上是同步任务的调度程序,例如,在阻塞时,一个任务被挂起,另一个任务被启动,依此类推,并且一旦任务被执行,任务又被恢复。畅通无阻的[source]
在给定的github示例中,首先定义了返回Async::Task
的echo_server方法,并将其分配给服务器变量 server
现在已创建变量,基础任务开始在套接字上侦听并被client.read(512)
调用阻塞。它被挂起,流到达循环部分,其中5个客户端Async::Task
一对一地向套接字写入消息。
现在发生了我不了解的事情。服务器任务被解锁并回复第一条消息。在那之后它应该退出,因为没有任何循环。但是,它可以处理所有五个请求,然后退出。显然我出了点问题,但是我无法弄清楚。任何评论都将受到高度赞赏。
答案 0 :(得分:0)
echo_client
会执行5次。该函数调用endpoint.connect
并发送一条消息并读取一条响应。
echo_server
被执行1次并调用endpoint.accept
,这将为每个连接产生一个块。服务器读取一条消息并将其写回。
服务器任务被解锁并回复第一条消息。之后,应该退出,因为没有任何循环。
endpoint.accept
被实现为a loop:
def accept(backlog = Socket::SOMAXCONN, &block)
bind do |server|
server.listen(backlog)
server.accept_each(&block)
end
end
这里是implementation of server.accept_each
:
def accept_each(task: Task.current)
task.annotate "accepting connections #{self.local_address.inspect}"
while true
self.accept(task: task) do |io, address|
yield io, address, task: task
end
end
end
如您所见,它绑定到套接字,侦听传入的连接,然后在循环中调用accept。