簡體   English   中英

如何設置Cherrypy服務器發送的事件

[英]How to setup cherrypy server sent events

我正在開發一個簡單的Web應用程序,該應用程序已完成了Angular和Cherrypy(目前是原型)。 我正在上傳兩個文件,然后使用子進程(popen)在cherrypy中調用外部python程序來處理它們。 到目前為止,我已經能夠做到。 我要實現的是傳遞給客戶端的外部程序(我通過popen捕獲)的輸出。 我的問題是,我試圖在cherrypy上設置服務器發送的事件,但沒有成功。

這是我要公開的cherrypy方法(來自網絡的一個示例):

@cherrypy.expose
def getUpdate(self):
    #Set the expected headers...
    cherrypy.response.headers["Content-Type"] = "text/event-stream;charset=utf-8"
    def content():
         yield "Hello,"
         yield "world"
    return content()

這是javascript客戶端代碼(我啟用了CORS並且可以正常工作):

var sseEvent = new EventSource('http://localhost:8090/getUpdate');
sseEvent.onmessage = function (event) {
    console.log(event);
};
sseEvent.onopen = function (event) {
  //console.log("I have started...");
};

我已經看過這個問題,並在這個博客中 但是,從服務器端調用函數時,EventSource對象上的onmessage事件未觸發。 我的理解是,您可以從服務器端調用該函數,它將捕獲來自瀏覽器的事件。 我錯了或者設置錯了?

因此,我發現使用SSE時,我需要以特定格式發送數據。

  • 數據:“ foo \\ n \\ n”

或json

  • data: "{\\n data: "msg" : "foo", \\n data: "id" : "boo", \\n data: "}\\n\\n

我想要的是一種重試格式,以在n秒后繼續輪詢服務器。 因此,cherrypy函數現在是:

@cherrypy.expose
def getUpdate(self, _=None):
    cherrypy.response.headers["Content-Type"] = "text/event-stream;charset=utf-8"
    if _:
        data = 'retry: 200\ndata: ' + str( self.prog_output) + '\n\n'
        return data
    else:
        def content():
            data = 'retry: 200\ndata: ' + str( self.prog_output) + '\n\n'
            return data
        return content()

getUpdate._cp_config = {'response.stream': True, 'tools.encode.encoding':'utf-8'}

,現在發送的消息帶有

“重試:n微秒”

這將每n微秒發送一次數據。 現在,EventSource onmessage事件被觸發,我很高興地從服務器發送的程序中讀取輸出。 :)

上SSE的好書(在許多帖子中都提到過): 這里

為了補充這個自我回答的問題,我制作了這個功能齊全的示例,其中包含兩個文件。

文檔非常有幫助。

祝大家開心!

的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>title</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div>server-sent events</div>
    <h3>sse_handler.onmessage()</h3>
    <ul id="sse_message"></ul>

<script>

    // create a sse handler
    var sse_handler = new EventSource('http://localhost:8080/getUpdate');

    sse_handler.onmessage = function (event) {
        console.log("-- sse_handler.onmessage()", event);
        /* the onmessage method catch all generic message, those with no event field
        */
        var h_ul = document.getElementById('sse_message');
        var h_li = document.createElement("li");

        h_li.innerHTML = event.data;
        h_ul.appendChild(h_li);
    };

    sse_handler.onopen = function (event) {
        console.log("-- sse_handler.onopen()", event);
    };

</script>
</body>
</html>

server.py

#!/usr/bin/env python3

import datetime

import cherrypy

from pathlib import Path

class TestServerSentEvent(object):
    @cherrypy.expose
    def index(self):
        return Path("index.html").read_text()

    @cherrypy.expose
    def getUpdate(self, * pos, ** nam):
        cherrypy.response.headers["Content-Type"] = "text/event-stream;charset=utf-8"
        return 'retry: 1200\ndata: {0}\n\n'.format(self.output())

    def output(self) :
        d = datetime.datetime.now()
        return f"TEST - {d}"

    getUpdate._cp_config = {'response.stream': True, 'tools.encode.encoding':'utf-8'}

if __name__ == '__main__':
    cherrypy.quickstart(TestServerSentEvent())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM