Ruby 中的套接字,如何通过套接字异步读取和写入数据



我正在尝试构建一个基于 ruby 的后台作业,这是建立 TCP 套接字连接并继续从其流中读取所必需的。 我需要打开同一个套接字来写入数据。

我知道套接字后面的服务器正在按预期工作,因为我还有其他服务可以使用它。

我试图跨越后台线程,继续读取流,但它从未获取数据

@socket = TCPSocket.new(localhost, 1234)

def read_data_loop
while true
@socket.each_line do |line|
p "data: #{line}"
end
end
end
@buffer_thread = Thread.new { read_data_loop }
@socket.write("send me something!!")
sleep(10)
@buffer_thread.exit

我渴望一个工作示例来实现这种异步读/写......

附言。我在这个例子中使用了TCPSocket因为它一开始就像一个好主意,但我并不相信它。我会采取任何有用的东西

根据 Casper 在问题评论中的建议,我将 proc 更改为使用IO.select。它像微风一样工作。

首先要知道的是,当缓冲区中没有数据时尝试读取套接字(@socket.recv)将使套接字"挂起"等待来自服务器的新消息。这有一个烦人的副作用,即阻止我们写入套接字(通过分离的线程)。 因此,为了解决这个问题,IO.select调用将尝试读取袜子 2 秒(2 用作下面的最后一个参数)。当 2 秒过去没有数据时,IO.select返回nil这让我在知道它会"挂起"时不调用@socket.recv

一个很大的副作用是,当没有数据时,我的while true不会杀死客户端,因为IO.select每个循环需要 2 秒才能超时。

这是最终结果:

@socket = TCPSocket.new(localhost, 1234)

def read_data_loop
while true
while IO.select([@socket], nil, nil, 2) && (line = @socket.recv(50))
p line
end
end
end
@buffer_thread = Thread.new { read_data_loop }
@socket.write("send me something!!")
sleep(10)
@buffer_thread.exit

这让后台线程写入控制台:

server response
hi there

因为这是我在服务器上设置的两条消息。

最新更新