【发布时间】:2015-05-19 15:36:20
【问题描述】:
我使用 Sinatra::Streaming(我使用 Ruby)编写了一个 HTTP 服务器 (A)。它需要从 WebSocket 服务器 (B) 读取数据并将其转发给客户端 (C)。数据流是“B-->A-->C”。读写操作应该是实时的。
作为一种可能的解决方案,我尝试在 Sinatra 中创建一个 WebSocket 连接。代码是这样的:
class Deploy < Sinatra::Base
helpers Sinatra::Streaming
set :sessions, true
set :server, 'thin'
get '/' do
stream(:keep_open) do |out|
#create a WebSocket connection
EM.run {
ws = Faye::WebSocket::Client.new('ws://0.0.0.0:8080/')
ws.on :message do |event|
out << event.data
out.flush
end
ws.on :close do |event|
ws = nil
end
}
end
end
end
我已经尝试了几个 WebSocket 客户端库,例如 faye-websocket。程序在执行out << event.data 时以~/.rvm/gems/ruby-2.0.0-p598/gems/sinatra-contrib-1.4.2/lib/sinatra/streaming.rb:100:in '<<': not opened for writing (IOError) 失败。 WebSocket 连接同时关闭。
好像是WebSocket的IO冲突/关闭了Sinatra Stream的IO。
我目前创建了一个子进程来建立WebSocket连接,并让子进程与Sinatra服务器(A)进行通信。但是如果有几十个人访问A,可能会消耗过多的系统资源。而且,当客户端过多或等待时间过长时,Sinatra Stream 服务器也经常为not opened for writing (IOError) 中止。
所以我的问题是
- 如何在HTTP流服务器中实现WebSocket客户端? (可以使用其他库代替 Sinatra)
- 如果可以在Sinatra Stream中实现WebSocket客户端,如何提高Sinatra Stream服务器的稳定性? (避免 IOError)
对不起,我的英语很差。非常感谢!
【问题讨论】:
-
我也遇到了同样的问题,你找到解决办法了吗?
-
我忘记了解决方案的细节。但是你可以更新 Ruby 的版本来避免这个错误(>=ruby-2.1 似乎没问题)。我还在每两个“写入”之间添加了几微秒的“睡眠”。希望对您有所帮助!
标签: ruby sinatra http-streaming em-websocket