2017-01-03 112 views
1

我在调查使用Flask应用程序作为嵌入式系统接口的可能性。我之前使用过烧瓶(我已经写了一些非常基本的烧瓶站点来轮询外部系统以响应页面加载以填充图表),但我不知道如何将数据推送到Flask应用程序并传递给用户的浏览器。如何通过烧瓶应用程序流式传输数据?

我打算使用ZeroMQ将数据从运行在嵌入式设备上的C++应用程序推送到烧瓶应用程序(也在嵌入式设备上运行)。

从我读过的东西,像flask-socketIO这样的东西可能会从Flask中获取东西到用户的浏览器。

我不清楚的一件事是,是否有可能/如何从ZeroMQ接收数据并将其推送到浏览器?

+0

可能是[另一SO交](HTTP的副本:// stackoverflow.com/questions/27548880/updating-webpage-from-background-thread-using-socket-io-but-without-event-trigge)如果使用后台线程是正确的方法? –

+0

我用websockets和gevent完成了它,它工作得很好。可以看看我的例子在这里:https://github.com/reptillicus/zmq/blob/master/exmaples/diffusion/web_server/server.py – reptilicus

+0

此外,我试过socketio,发现它是一片狗屎 – reptilicus

回答

4

如果任何人想要做的一样,这是下降到基于由reptilicus的例子,我可以煮东西最简单的例子...

说明

  1. 设置下面的代码奠定在下面提到的结构中。
  2. 安装Python模块下面列出
  3. 运行服务器
  4. 运行数据源
  5. 打开Web浏览器,然后导航至http://localhost:25000/

如果一切正常,你应该一起看到一个非常基本的网页这些行:

enter image description here

PYT hon/Modules

这些是我的测试实现使用的版本。其他人也可能工作。

  • 的Python V3.5.2
  • Pyzmq v15.2.0
  • GEVENT V1.2.0
  • karellen-geventws V1.0.1(需要过度GEVENT-的WebSocket为Python 3的支持)
  • 瓶V0。 10.1
  • 烧瓶套接字v0.2.1

您还需要Reconnecting Websocket副本,availab le here

代码布局

\ZmqFlaskForwarder 
    \static 
     \js 
      application.js 
      reconnecting-websocket.min.js 
    \templates 
     index.html 
    data_source.py 
    server.py 

服务器应用程序(server.py)

import zmq.green as zmq 
import json 
import gevent 
from flask_sockets import Sockets 
from flask import Flask, render_template 
import logging 
from gevent import monkey 

monkey.patch_all() 

app = Flask(__name__) 
logging.basicConfig(level=logging.INFO) 
logger = logging.getLogger(__name__) 

sockets = Sockets(app) 
context = zmq.Context() 

ZMQ_LISTENING_PORT = 12000 

@app.route('/') 
def index(): 
    logger.info('Rendering index page') 
    return render_template('index.html') 

@sockets.route('/zeromq') 
def send_data(ws): 
    logger.info('Got a websocket connection, sending up data from zmq') 
    socket = context.socket(zmq.SUB) 
    socket.connect('tcp://localhost:{PORT}'.format(PORT=ZMQ_LISTENING_PORT)) 
    socket.setsockopt_string(zmq.SUBSCRIBE, "") 
    poller = zmq.Poller() 
    poller.register(socket, zmq.POLLIN) 
    gevent.sleep() 
    received = 0 
    while True: 
     received += 1 
     # socks = dict(poller.poll()) 
     # if socket in socks and socks[socket] == zmq.POLLIN: 
     data = socket.recv_json() 
     logger.info(str(received)+str(data)) 
     ws.send(json.dumps(data)) 
     gevent.sleep() 

if __name__ == '__main__': 
    logger.info('Launching web server') 
    from gevent import pywsgi 
    from geventwebsocket.handler import WebSocketHandler 
    server = pywsgi.WSGIServer(('', 25000), app, handler_class=WebSocketHandler) 
    logger.info('Starting serving') 
    server.serve_forever() 

数据源(DATA_SOURCE。PY)

import zmq 
import random 
import sys 
import time 
import json 

port = "12000" 

context = zmq.Context() 
socket = context.socket(zmq.PUB) 
socket.bind("tcp://*:%s" % port) 
while True: 
    first_data_element = random.randrange(2,20) 
    second_data_element = random.randrange(0,360) 
    message = json.dumps({'First Data':first_data_element, 'Second Data':second_data_element}) 
    print(message) 
    socket.send_string(message) 
    time.sleep(0.5) 

客户机JavaScript(的application.js)

ws = new ReconnectingWebSocket("ws://" + location.host + '/zeromq') 

ws.onmessage = function(message) { 
    payload = JSON.parse(message.data); 
    $('#latest_data').html('<h2> Data: ' + message.data + '</h2>'); 
}; 

模板(的index.html)

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Python Websockets ZeroMQ demo</title> 
    </head> 
    <body> 
    <div class="container"> 
     <h2> Simple ZeroMQ data streaming via web sockets! </h2> 
     <div id="latest_data"></div> 
    </div> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> 
    <script type="text/javascript" src="static/js/reconnecting-websocket.min.js"></script> 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.6/d3.min.js"></script> 
    <script type="text/javascript" src="static/js/application.js"></script> 
    </body> 
</html> 
+0

这是我查找了一段时间了。谢谢。在一台PC上它是完美的,另一个 - 当我关闭一个页面时,它显示一个错误* geventwebsocket.exceptions.WebSocketError:Socket死了..dist-packages/geventwebsocket/websocket.py *但是另一台PC是完美的。日Thnx – jaromrax