Reputation: 379
I created a route /stream
which should push the string 'test' every second.
When I open this URL (localhost:12346/stream
) on Chrome, it indeed opens a blank page and a "test" is appended to the page every second, so I think the server side is working correctly. When I opened it on Firefox, it treats it as a file download that never finishes.
But when I open client.html
below, the onmessage
event of the EventSource object is never fired so I get no data. The onopen
event was fired and I see it in the console. Why is this? How can I receive the data in the JavaScript side?
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>
Upvotes: 1
Views: 4845
Reputation: 571
Though it was later for years.. I faced the same problem with you (message appended to the page but not fired to EventStream)
After search so much examples & test for hours I found some key
You need to yield message with data:
prefix and \n
suffix, like data:test\n\n
So this should work for you.
def event_stream():
while True:
time.sleep(1)
yield 'data:test\n\n'
And you can see the EventStream with Type=message, Data=test
in Chrome Debug Tools (as also source.onmessage
)
I think it has another key word like data:
, but I didn't find out the document about this, maybe someone can supplement.
Upvotes: 6
Reputation: 11
you can avoid this problem by add @cross_origin() in your code.
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)
This is the html file
<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>
Upvotes: 1
Reputation: 31
That resolved my problem, backend was sending events with custom type which not triggers onmessage callback
Upvotes: 3