Я начал изучать события, отправляемые сервером, и мне стало интересно попробовать их с моими любимыми инструментами: Python, Flask и Twisted. Я спрашиваю, нормально ли спать так, как я это делаю, по сравнению со способом gevent greenlet.sleep, это мой очень простой код, взятый и «портированный» в Twisted (из gevent):
#!/usr/bin/env python
import random
from twisted.web.server import Site
from twisted.web.wsgi import WSGIResource
from twisted.internet import reactor
import time
from flask import Flask, request, Response
app = Flask(__name__)
def event_stream():
count = 0
while True:
count += 1
yield 'data: %c (%d)\n\n' % (random.choice('abcde'), count)
time.sleep(1)
@app.route('/my_event_source')
def sse_request():
return Response(
event_stream(),
mimetype='text/event-stream')
@app.route('/')
def page():
return '''
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="//code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
sse = new EventSource('/my_event_source');
sse.onmessage = function(message) {
console.log('A message has arrived!');
$('#output').append('<li>'+message.data+'</li>');
}
})
</script>
</head>
<body>
<h2>Demo</h2>
<ul id="output"></ul>
</body>
</html>
'''
if __name__ == '__main__':
resource = WSGIResource(reactor, reactor.getThreadPool(), app)
site = Site(resource)
reactor.listenTCP(8001, site)
reactor.run()
Хотя time.sleep является блокирующей функцией, она не заблокирует Twisted реактор, и это должно быть доказано тем фактом, что несколько разных браузеров могут получить доступ к странице и правильно получить событие: в этом случае необходимо использовать разные браузеры, поскольку Chromium при этом несколько разных запросов с одним и тем же URI будут поставлены в очередь, и, поскольку это потоковый ответ, эта очередь браузера будет занята до тех пор, пока сокет или запрос не будут закрыты. Каковы ваши трудности? Есть ли лучший способ? Не так много примеров кода по этому поводу с Twisted и Flask.