首页 > 解决方案 > 带有js事件源的Flask事件流应用程序覆盖以前的流输出

问题描述

我的烧瓶应用程序:

import eventlet

eventlet.monkey_patch()

from flask import Flask, render_template, Response
from shelljob import proc
from time import sleep

app = Flask(__name__)

@app.route('/')
def index():
  return render_template('stream.html')

@app.route('/stream')
def stream():
    g = proc.Group()
    p = g.run([ "bash", "-c", "sudo tcpdump -i ens4 -s 0 -nX tcp port 5000" ])
    def read_process():
        while g.is_pending():
            lines = g.readlines()
            for proc, line in lines:
                yield "data:" + str(line) + "\n\n"

    return Response(read_process(), mimetype='text/event-stream')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001)

流.html

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <h1>Output</h1>
    <div id="dumps"></div>
</body>
    <script>
      var targetContainer = document.getElementById("dumps");
      var eventSource = new EventSource("/stream");
      eventSource.onmessage = function(e) {
          targetContainer.innerHTML = e.data;
      };
    </script>
</html>

我的问题:

输出似乎到达浏览器,但任何新的流式输出都会覆盖前一个。例如,以下是我在浏览器中看到的所有内容,并且随着流的更新,该行会不断变化:

Output

b'\t0x0020: 8011 01fa ce65 0000 0101 080a 1984 6ce7 .....e........l.\n'   <=== keeps updating 

我想要实现的是在我的浏览器上呈现的 tcpdump 输出流,就像实际的 bash 输出一样。

如果我指向 url 路径/stream并且我嵌入到 html 中的原因是能够给它一些风格,这很好用。

标签: javascriptflask

解决方案


改为targetContainer.innerHTML += e.data + "<br/><script>


推荐阅读