3

我使用 Sinatra::Streaming(我使用 Ruby)编写了一个 HTTP 服务器(A)。它需要从 WebSocket 服务器 (B) 读取数据并将其转发给客户端 (C)。数据流是“B-->A-->C”。读写操作应该是实时的。

作为一种可能的解决方案,我尝试在 Sinatra 中创建一个 WebSocket 连接。代码是这样的:</p>

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。程序~/.rvm/gems/ruby-2.0.0-p598/gems/sinatra-contrib-1.4.2/lib/sinatra/streaming.rb:100:in '<<': not opened for writing (IOError)在执行时失败out << event.data。WebSocket 连接同时关闭。

似乎WebSocket的IO冲突/关闭了Sinatra Stream的IO。

我目前创建了一个子进程来建立WebSocket连接,并让子进程与Sinatra服务器(A)进行通信。但是如果有几十个人访问A,可能会消耗过多的系统资源。而且,Sinatra Stream 服务器也经常因为not opened for writing (IOError)客户端过多或等待时间过长而中止。

所以我的问题是

  1. 如何在 HTTP 流服务器中实现 WebSocket 客户端?(可以使用其他库代替 Sinatra)
  2. 如果可以在 Sinatra Stream 中实现 WebSocket 客户端,如何提高 Sinatra Stream 服务器的稳定性?(避免 IOError)

对不起我的英语不好。非常感谢!

4

1 回答 1

0

问题发生在很久以前,我忘记了解决方案的细节。但是根据我的记忆力弱,你可以更新 Ruby 的版本来避免这个错误(>=ruby-2.1 似乎还可以)。我还在每两个“写入”之间添加了几微秒的“睡眠”。

我相信Ruby的版本是主要原因。抱歉,我现在无法测试。

于 2015-11-13T22:12:22.843 回答