Javascript 服务器使用Ruby Grape发送事件
我正在尝试在我的服务器上创建服务器发送的事件。 问题是连接似乎总是很快关闭,因为我一直在测试网页上看到Javascript 服务器使用Ruby Grape发送事件,javascript,ruby,server-sent-events,grape,Javascript,Ruby,Server Sent Events,Grape,我正在尝试在我的服务器上创建服务器发送的事件。 问题是连接似乎总是很快关闭,因为我一直在测试网页上看到connectionclosed事件 客户端连接到服务器,因为我可以看到调用的方法,但是我想知道为什么连接不是常量,为什么我不接收使用线程发送的数据 以下是我的Ruby代码: $connections = [] class EventsAPI < Sinantra::Base def connections $connections end get "/" do
connectionclosed
事件
客户端连接到服务器,因为我可以看到调用的方法,但是我想知道为什么连接不是常量,为什么我不接收使用线程发送的数据
以下是我的Ruby代码:
$connections = []
class EventsAPI < Sinantra::Base
def connections
$connections
end
get "/" do
content_type "text/event-stream"
stream(:keep_open) { |out|
puts "New connection"
out << "data: {}\n\n"
connections << out
}
end
post "/" do
data = "data\n\n"
connections.each { |out| out << data }
puts "sent\n"
end
end
编辑:我使用GET方法实现了它(我将Grape::API更改为Sinatra::Base,因为Grape没有实现流)。我现在接收数据,但连接没有保持活动状态,当我使用post方法时,数据永远不会到达浏览器
提前感谢您的回答。JS代码看起来是正确的。我的猜测是,您不应该为无限循环启动新线程。将要发生的是,主线程将继续执行,到达其块的末尾,并关闭http请求。然后,将分离的线程留在不存在的
out
流中写入
更新以响应您的编辑:SSE不支持POST。只有使用GET Data或cookies才能将数据传递给SSE流程。我刚刚回答了这个问题,但是如果您在葡萄API中遵循一个专门针对SSE的示例,那么发布一个指向该文档的链接将非常有用。(我特别想知道
:keep_open
到底做了什么。)我删除了循环和线程,只是为了确保我得到了数据。它可以工作(见上文),但连接不能保持活动状态。您需要无限循环:只要进程结束,SSE连接就会关闭。
var source = new EventSource('http://localhost:9292/events');
source.onmessage = function(e) {
console.log("New message: ", e.data);
showMessage(e.data);
};
source.onopen = function(e) {
// Connection was opened.
};
source.onerror = function(e) {
console.log("Source Error", e)
if (e.eventPhase == EventSource.CLOSED) {
console.log("Connection was closed");
// Connection was closed.
}
};
var showMessage = function(msg) {
var out = document.getElementById('stream');
var d = document.createElement('div')
var b = document.createElement('strong')
var now = new Date;
b.innerHTML = msg;
d.innerHTML = now.getHours() + ":" + now.getMinutes() + ":" +now.getSeconds() + " ";
d.appendChild(b);
out.appendChild(d);
};