带Puma的Sinatra流式传输?

9
我正在尝试在我的应用程序中利用服务器发送事件。我正在使用Sinatra和sinatra-sse gem。这个gem包装了Sinatra的stream :keep_alive调用。
当我在Thin上运行我的应用程序时,我完全没有问题,我的事件流按预期工作。然而,当我将我的应用程序切换到使用Puma时,除了我的sse_stream什么也不做!它只返回一个空白页面。
我的流设置如下:
get "/logstream/:server" do
    if rbcserver = MyApp.servers[params[:server]]
        sse_stream do |stream|     
            rbcserver.add_web_logger(stream)
            stream.callback { rbcserver.remove_web_logger(stream) }
        end
    else
        error 404
    end
end

我这样启动Thin:

@@puma_instance = Puma::Server.new MyApp::WebUI
@@puma_instance.add_tcp_listener ip, port
@@puma_instance.run

有什么想法吗?任何帮助都将不胜感激。

编辑:更多信息 这是在Puma上运行时cURL给出的结果。

$ curl -L -b cookies.txt -c cookies.txt -i http://localhost:9001/logstream/myserver    
HTTP/1.1 200 OK
Content-Type: text/event-stream;charset=utf-8
X-Content-Type-Options: nosniff
Transfer-Encoding: chunked

$

相比之下,这就是在Thin上发生的情况

$ curl -L -b cookies.txt -c cookies.txt -i http://localhost:9001/logstream/myserver                                        
HTTP/1.1 200 OK
Content-Type: text/event-stream;charset=utf-8
X-Content-Type-Options: nosniff
Connection: close
Server: thin 1.5.1 codename Straight Razor

event: <event name>
data: <my data>

event: <event name>
data: <my data>

<continues as more data comes in>

编辑:我应该补充说明,我的应用程序在其核心中使用EventMachine,因此sinatra_sse与EM的耦合可能不是问题。

1个回答

3
我相信问题围绕sinatra-sse的显式使用EventMachine库,它没有列为依赖项。但是,在其Gemfile中列出了Thin,并且EventMachine是Thin的核心依赖项。
Puma的并发模型非常不同。实际上,您会在项目的README顶部找到以下声明:
Puma通过允许并行运行阻塞IO来提高MRI的吞吐量(基于EventMachine的服务器如Thin关闭此功能,需要使用特殊库)。 编辑 如果您对了解Rack、Rails、Puma和SSE感兴趣,您可能会喜欢由Ruby/Rails核心成员Aaron Patterson撰写的这篇精彩的博客文章

好的,我的应用程序也使用了EventMachine,所以我不认为这是由于EventMachine未运行引起的。而且你提供的那行代码似乎只用于在没有数据发送时保持连接开放。我的应用程序定期发送大量数据,所以我不认为这与此有任何关系 :/ - Ilya O.
1
@IlyaO. 我刚刚编辑了我的回答,并附上了一个链接,该链接指出了 Puma 实现 async.callback 的障碍。 - ezkl
刚刚提高了这个问题的优先级。如果没有其他人有什么要补充的,我会给你奖励。 - Ilya O.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接