即使Flask服务器推送似乎起作用,EventSource.onmessage也不会触发

时间:2019-05-10 11:53:47

标签: javascript html flask server-sent-events eventsource

我创建了一条路由/stream,该路由应该每秒输入一次字符串'test'。

当我在Chrome上打开此URL(localhost:12346/stream)时,它的确打开了一个空白页面,并且每秒都会在页面上附加一个“测试”,因此我认为服务器端可以正常工作。当我在Firefox上打开它时,它将其视为永远不会完成的文件下载。

但是,当我在下面打开client.html时,永远不会触发EventSource对象的onmessage事件,所以我没有任何数据。 onopen事件被触发,我在控制台中看到它。为什么是这样?如何在JavaScript端接收数据?

server.py:

import flask
import flask_cors
import time

app = flask.Flask(__name__)
app.debug = True
flask_cors.CORS(app)

def event_stream():
    while True:
        time.sleep(1)
        yield 'test\n'

@app.route('/stream')
def stream():
    return flask.Response(event_stream(), mimetype='text/event-stream')

app.run(port=12346, threaded=True)

client.html:

<!DOCTYPE html>
<html>
  <body>
    <script>
        var source = new EventSource('http://localhost:12346/stream');
        source.onopen = e => console.log('opened', event);
        source.onerror = e => console.log('error', event);
        source.onmessage = e => console.log('onmessage', event);
    </script>
  </body>
</html>

3 个答案:

答案 0 :(得分:1)

Server sent event EventStream does not trigger "onmessage" but Chrome Debug shows data in "EventStream" tab

这解决了我的问题,后端正在发送具有自定义类型的事件,而不会触发onmessage回调

答案 1 :(得分:0)

您可以通过在代码中添加@cross_origin()来避免此问题。

import flask
from flask_cors import cross_origin
import time

app = flask.Flask(__name__)

@app.route('/stream')
@cross_origin()
def stream():
    def event_stream():
        while True:
            yield "data:" + "test" + "\n\n"
            time.sleep(1)

    return flask.Response(event_stream(), mimetype='text/event-stream')

app.run(port=12346)

这是html文件

<html>
  <head>
  </head>
  <body>

    <script>

    var source = new EventSource('http://127.0.0.1:12346/stream');
    console.log(source)
    source.onmessage = function(event) {
        console.log(event.data);        
    }

    </script>

  </body>

</html>

答案 2 :(得分:0)

虽然晚了很多年.. 我和你遇到了同样的问题(消息附加到页面但没有被触发到 EventStream

在搜索了这么多示例并测试了几个小时后,我找到了一些关键

您需要产生带有 df.replace({"sequence":D}).groupby(['id','sequence'])['time'].mean() id sequence 1 4 0.0 preferred or discarded 9.0 safe 4.5 2 4 4.0 preferred or discarded 10.0 safe 4.0 3 5 3.5 preferred or discarded 9.5 前缀和 data: 后缀的消息,例如 \n

所以这应该适合你。

data:test\n\n

您可以在 Chrome 调试工具中看到带有 def event_stream(): while True: time.sleep(1) yield 'data:test\n\n' 的 EventStream(还有 Type=message, Data=test

我觉得它还有一个关键字,比如source.onmessage,但是我没有找到关于这个的文档,也许有人可以补充。