如何通过烧瓶应用程序传输数据?

时间:2017-01-03 12:34:22

标签: python flask socket.io streaming

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

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

从我所读过的内容中,flask-socketIO之类的内容可以将Flask中的内容传递给用户的浏览器。

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

1 个答案:

答案 0 :(得分:7)

如果其他人想要这样做,这是最简单的例子,我可以根据reptilicus的例子将事情简化为......

说明

  1. 设置以下结构中列出的代码。
  2. 安装下面列出的Python模块
  3. 运行服务器
  4. 运行数据源
  5. 打开网络浏览器并导航至http://localhost:25000/
  6. 如果一切正常,你应该看到一个非常基本的页面:

    enter image description here

    Python / Modules

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

    • Python v3.5.2
    • Pyzmq v15.2.0
    • gevent v1.2.0
    • karellen-geventws v1.0.1(需要通过gevent-websocket支持Python 3)
    • Flask v0.10.1
    • Flask-Sockets v0.2.1

    您还需要Reconnecting Websocket的副本,可用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>