如何通过 Flask 应用程序流式传输数据? [英] How do I stream data through a flask application?

查看:75
本文介绍了如何通过 Flask 应用程序流式传输数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究使用 Flask 应用程序作为嵌入式系统接口的可能性.我以前使用过flask(例如,我编写了一些非常基本的flask 站点来轮询外部系统以响应页面加载以填充图表)但我不确定如何将数据推送到Flask 应用程序中并转到用户的浏览器.

我计划使用

Python/模块

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

  • 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

您还需要重新连接 Websocket 的副本,可在此处.

代码布局

mqFlaskForwarder静止的js应用程序.js重新连接-websocket.min.js模板索引.html数据源.py服务器.py

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

将 zmq.green 导入为 zmq导入json导入 gevent从flask_sockets 导入套接字从烧瓶导入烧瓶,render_template导入日志从 gevent 进口猴子猴子.patch_all()app = Flask(__name__)logging.basicConfig(level=logging.INFO)logger = logging.getLogger(__name__)套接字 = 套接字(应用程序)上下文 = zmq.Context()ZMQ_LISTENING_PORT = 12000@app.route('/')定义索引():logger.info('渲染索引页')返回 render_template('index.html')@sockets.route('/zeromq')定义发送数据(ws):logger.info('有一个 websocket 连接,从 zmq 发送数据')socket = context.socket(zmq.SUB)socket.connect('tcp://localhost:{PORT}'.format(PORT=ZMQ_LISTENING_PORT))socket.setsockopt_string(zmq.SUBSCRIBE, "")轮询器 = zmq.Poller()poller.register(套接字,zmq.POLLIN)gevent.sleep()收到 = 0而真:收到 += 1# 袜子 = dict(poller.poll())# if socket in socks and socks[socket] == zmq.POLLIN:数据 = socket.recv_json()logger.info(str(received)+str(data))ws.send(json.dumps(data))gevent.sleep()如果 __name__ == '__main__':logger.info('启动网络服务器')从 gevent 导入 pywsgi从 geventwebsocket.handler 导入 WebSocketHandlerserver = pywsgi.WSGIServer(('', 25000), app, handler_class=WebSocketHandler)logger.info('开始服务')server.serve_forever()

数据源(data_source.py)

导入zmq随机导入导入系统导入时间导入json端口 = "12000"上下文 = zmq.Context()socket = context.socket(zmq.PUB)socket.bind("tcp://*:%s" % 端口)而真:first_data_element = random.randrange(2,20)second_data_element = random.randrange(0,360)message = json.dumps({'第一个数据':first_data_element,'第二个数据':second_data_element})打印(消息)socket.send_string(消息)时间.睡眠(0.5)

客户端 JavaScript (application.js)

ws = new ReconnectingWebSocket("ws://" + location.host + '/zeromq')ws.onmessage = 函数(消息){有效载荷 = JSON.parse(message.data);$('#latest_data').html('<h2> 数据:' + message.data + '</h2>');};

模板 (index.html)

<头><title>Python Websockets ZeroMQ 演示</title><身体><div class="容器"><h2>通过 Web 套接字的简单 ZeroMQ 数据流!<div id="latest_data"></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>

I'm investigating the possibility of using a Flask application as an interface to an embedded system. I've used flask before (I've written some very basic flask sites to poll external systems in response to a page load to populate a chart for example) but I'm not sure how I would go about pushing data into the Flask application and on to the user's browser(s).

I was planning on pushing data from a C++ application running on the embedded device into the flask application (also running on the embedded device) using ZeroMQ.

From what I've read, something like flask-socketIO would be a possibility to get things from Flask to the user's browser.

The one thing that's not clear to me is whether it's possible / how you would go about receiving data from ZeroMQ and pushing that out to the browser?

解决方案

In case anyone else wants to do the same, this is the simplest example I could boil things down to based on the example by reptilicus...

Instructions

  1. Set the code below laid out in the structure mentioned below.
  2. Install the Python modules listed below
  3. Run the server
  4. Run the data source
  5. Open a web browser and navigate to http://localhost:25000/

If everything worked you should see a very basic page along these lines:

Python / Modules

These were the versions my test implementation used. Others may work too.

  • Python v3.5.2
  • Pyzmq v15.2.0
  • gevent v1.2.0
  • karellen-geventws v1.0.1 (required over gevent-websocket for Python 3 support)
  • Flask v0.10.1
  • Flask-Sockets v0.2.1

You also need a copy of Reconnecting Websocket, available here.

Code layout

mqFlaskForwarder
    static
        js
            application.js
            reconnecting-websocket.min.js
    	emplates
        index.html
    data_source.py
    server.py

Server App (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 (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)

Client 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>');
};

Template (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>

这篇关于如何通过 Flask 应用程序流式传输数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆