2015-04-01 45 views
1

我正在尝试在我的Ruby Grape API上创建服务器发送的事件。 问题是,连接似乎总是非常快速地关闭,因为我一直在测试网页上获取Connection closed事件。服务器发送的Ruby葡萄事件

客户端连接到服务器,因为我可以看到被调用的方法,但我想知道为什么连接不是恒定的,为什么我没有收到我使用线程发送的数据。

这里是我的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 

这里是我的javascript:

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); 
    }; 

编辑:我得到了它与GET方法的工作(我改变了葡萄:: API来西纳特拉: :葡萄基础不实现流)。我现在接收数据,但连接不会保持活动状态,当我使用post方法时,数据永远不会到达浏览器。

非常感谢您的回答。

+0

我刚刚回答,但是如果您在Grape API中专门针对SSE的示例,那么发布指向该文档的链接将非常有用。 (特别是我想知道'keep_open'究竟做了什么。) – 2015-04-01 17:00:55

回答

0

JS代码看起来正确。我的猜测是,你不应该为你的无限循环启动一个新的线程。会发生什么情况是主线程将继续执行,到达其块的末尾并关闭http请求。然后,您分离的线程将被写入不存在的out流。

对您编辑的回复进行更新: SSE不支持POST。数据只能通过使用GET数据或cookie传递给SSE进程。

+0

我删除了循环和线程,以确保我获得了数据。它的工作原理(见上文),但连接并不活跃。 – Manny42 2015-04-02 08:07:53

+0

您需要无限循环:只要您的流程结束,SSE连接就会关闭。 – 2015-04-02 10:18:01