我正在构建一个web服务器,它需要读取(并继续读取)它运行的机器的串行端口。
其目的是能够读取条形码扫描仪,并使用服务器发送的事件用读取的条形码更新浏览器。
我用烧瓶来做这个。我浏览了一下,有些实现只需要flask,有些说我需要一个像Gevent这样的异步库,有些甚至说我需要Gevent和一些像Redis或RabbitMQ这样的队列。
我试图将代码建立在stackoverflowhere上的一个非常简单的示例上。我有它的主要工作,但我被困在一些问题
我的代码如下(为清楚起见,简称)
服务器端:
from flask import Flask
import flask
import serial
app = Flask(__name__)
app.debug = True
def event_barcode():
ser = serial.Serial()
ser.port = 0
ser.baudrate = 9600
ser.bytesize = 8
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.open()
s = ser.read(7)
yield 'data: %s\n\n' % s
@app.route('/barcode')
def barcode():
newresponse = flask.Response(event_barcode(), mimetype="text/event-stream")
newresponse.headers.add('Access-Control-Allow-Origin', '*')
return newresponse
if __name__ == '__main__':
app.run(port=8080, threaded=True)
客户端:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>TEST</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script>
$(document).ready(function(){
if (!!window.EventSource) {
console.log('SSE supported.');
var source = new EventSource('http://localhost:8080/barcode');
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
console.log('Connection was opened.');
}, false);
source.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
console.log('Connection was closed.');
}
}, false);
} else {
console.log('SSE notsupported.');
}
});
</script>
</head>
<body>
</body>
</html>
我在这里看到了更多的信息: http://www.socketubs.net/2012/10/28/Websocket_with_flask_and_gevent/http://sdiehl.github.com/gevent-tutorial/#chat-server
我希望有人能澄清我的问题,也许能给我一些解决方案,交叉起源和3秒延迟问题。
谢谢。
回答我自己的问题
对于代码:
因为我想支持多个浏览器,所以SSE现在不是我的选择。我会查一下websockets并尝试从中学习。
以下是一些可能有帮助的建议(我一直想发布一些类似基于“django sse”的“flask sse”:
https://gist.github.com/3680055
https://gist.github.com/3687523
也有用-https://github.com/jkbr/chat/blob/master/app.py
“redissestream”类使用redis作为后端在线程之间进行通信(尽管gevent可以做到这一点?),并“侦听”redis发布事件。
虽然“PeriodicSseStream”不需要redis,但它不能在烧瓶线程之间进行通信,即使用来自另一个响应的信息;没有像redis这样的东西,单独的线程(流和为另一个用户服务的线程)就不能通信。
正如Janus所说,生成器只返回一个结果-它必须产生多个结果,在这种情况下,它必须被封装在一个循环中,在每次串行轮询之后都会无休止地产生结果;您还需要决定什么将限制轮询,它是受时间限制(定期轮询)还是其他限制(例如,如果读取串行端口已经花了一段时间)?
我不太了解sse的性能,也不知道它的支持程度(以及wrt跨域),但是如果考虑socket.io,您可以使用this来改进web套接字performance?
相关问题 更多 >
编程相关推荐