为什么浏览器不通过Flask socketIO中的这种实时推送进行更新?

时间:2018-09-16 21:36:32

标签: javascript python html flask socket.io

我是Flask的新手,对Javascript有点生锈。我需要在外部使用python生成事件并将其实时推送到网页,因此我选择了Flask-SocketIO。我建立了一个我能想到的最简单的例子:

from flask_socketio import SocketIO, emit
from flask import Flask, render_template
from time import sleep
from threading import Thread, Event    

app = Flask(__name__)
app.config['SECRET_KEY'] = 'haha!'
app.debug = True
socketio = SocketIO(app)    

thread = Thread()
thread_stop_event = Event()    

class MyThread(Thread):
    def __init__(self):
        super(MyThread, self).__init__()    

    def ticker(self):
        print("ticking")
        while not thread_stop_event.isSet():
            text="hi there"
            print(text)
            socketio.emit('message', {'data': text})
            sleep(1)    

    def run(self):
        self.ticker()    

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

@socketio.on('connect')
def test_connect():
    global thread
    print('Client connected')    

    if not thread.isAlive():
        print("Starting Thread")
        thread = MyThread()
        thread.start()    

@socketio.on('disconnect')
def test_disconnect():
    print('Client disconnected')    

if __name__ == '__main__':
    socketio.run(app)

在模板目录中包含以下index.html文件:

<html>
<head>
<title>Ticker</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
    var socket = io.connect('http://127.0.0.1:5000');
    socket.on('connect', function() {
        socket.send('User has connected!');
    });
    socket.on('message', function(text) {
        $("#messages").append('<li>'+text+'</li>');
        console.log('Received message');
    });
});
</script>
<ul id="messages"></ul>
</body>
</html>

我在控制台中看到“ hi there”的列表,但是在localhost:5000的浏览器中什么都没有。它似乎挂起了-浏览器底部显示“正在等待缓存”或“正在等待本地主机”。有人可以找出我在做什么错吗?在此先感谢您!

1 个答案:

答案 0 :(得分:0)

好的,我正在回答这个问题的任何人都需要使用Flask和socketIO将外部进程发送消息到浏览器。我花了大量时间在Google搜索和Stackoverflowing上,但从未找到一个真正简单,干净的示例,因此,这是我所能做到的。

这就是我想要的:使用Python,Flask和SocketIO,并使外部进程运行来发送将在浏览器中显示的消息。我的第一个选项是我写的一个问题,即生成带有外部进程的线程。我最终要做的是将一个不同的Python程序作为外部进程,对于我的应用程序(一个自动传感器报告器)来说,它实际上更好。因此,我是不是在准确地回答我的问题。但是,正如我所写的那样,我希望将这个答案放在这里有用,因为我从未找到一个简单的示例来说明如何做到这一点。在这里。

我认为基本问题是您需要某种负载平衡,以使外部进程通过socketio发送消息,因为代码不知道它是从1个程序还是从10,000个程序接收消息。在我看来,最简单的方法最终就是使用Redis。因此,您需要在代码运行时启动Redis并运行。在装有Homebrew的Mac上,您可以通过以下方式安装redis:

computed: {
  groups () {
    return this.cars.reduce((carry, current) => {
      if (carry.hasOwnProperty(current.make) && Array.isArray(carry[current.make])) {
        carry[current.make].push(current.model)
      } else {
        Object.assign(carry, { [current.make]: [current.model] })
      }
      return carry
    }, {})
  }
}

然后运行它

<div v-for="(make, index) in Object.keys(groups)" :key="index">
  <p>Make: {{ make }}</p>
  <ul>
  <li v-for="(model, innerIndex) in groups[make]" :key="innerIndex">
    {{ model }}
  </li>
  </ul>
</div>

(显然有一些方法可以使其在启动时启动。)这是我的服务器代码main.py

$ brew install redis

这是我的外部流程代码broadcast.py

$ redis-server /usr/local/etc/redis.conf

这是模板目录中的html代码index.html:

from flask import Flask, render_template
from flask_socketio import SocketIO    

app = Flask(__name__)
app.config['SECRET_KEY'] = 'slivovitz'
app.debug = True
socketio = SocketIO(app, message_queue='redis://')    

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

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

如果您希望在Raspberry Pi上完成整个工作,请使用https://www.alibabacloud.com/blog/how-to-install-and-configure-redis-server-on-debian-9_472211安装redis。就是那么容易。享受