我正在构建一个需要读取(并继续读取)它正在运行的机器的串行端口的网络服务器。
目的是能够读取条形码扫描仪,并使用服务器发送的事件来使用读取的条形码更新浏览器。
我正在使用烧瓶来做到这一点。我浏览了一下,有些实现只需要烧瓶,有些人说我需要一个像 Gevent 这样的异步库,还有一些人甚至说我需要 Gevent 和某种队列,比如 Redis 或 RabbitMQ。
我试图将我的代码基于我在 stackoverflow 上找到的一个非常简单的示例。我大部分时间都在工作,但我遇到了一些问题;
- 在 Chrome 中存在跨域错误,通过添加 Access-Control-Allow-Origin 标头,我可以让它在 FireFox 中工作,但 Chrome 仍然无法工作。只有FF支持SSE跨域对吗?我需要它来支持 CORS,因为浏览器需要从单独的机器加载条形码数据。
- 每条消息后,浏览器都会在控制台中显示条形码,但随后会关闭连接,大约 3 秒后才再次打开。这似乎起源于 Flask,它给了我数据然后就停止了。
- 另外,我想知道这将如何在负载下执行。我的意思是,flask 为文本/事件流 mimetype 保持连接打开。如果有多个客户端连接,过一会会不会阻塞flask,因为所有的连接都会饱和?
我的代码如下(为清楚起见缩短了)
服务器端:
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 秒延迟问题。
谢谢。