2015-04-01 53 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