【问题标题】:Why isn't the browser updating with this real time push in Flask socketIO?为什么浏览器没有通过 Flask socketIO 中的实时推送进行更新?
【发布时间】:2018-09-16 21:36:32
【问题描述】:

我是 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>

我在控制台中看到了“你好”的列表,但在浏览器中的 localhost:5000 没有任何内容。它似乎挂了 - 浏览器底部显示“等待缓存”或“等待本地主机”。有人能弄清楚我做错了什么吗?提前非常感谢!

【问题讨论】:

    标签: javascript python html flask socket.io


    【解决方案1】:

    好的,我正在为任何遇到此问题的人回答这个问题,需要有一个外部进程使用 Flask 和 socketIO 将消息发送到浏览器。我花了很多时间谷歌搜索和 Stackoverflowing,但我从来没有找到一个真正简单、干净的例子,所以尽我所能。

    这就是我想要的:使用 Python、Flask 和 SocketIO,并让一个外部进程运行发送消息,这些消息将显示在浏览器中。我的第一次尝试是我写的一个问题,即用外部进程生成一个线程。我最终做的是让一个不同的 Python 程序作为外部进程,对于我的应用程序,一个机器人传感器报告器,它实际上更好。所以,对不起,我没有准确地回答我的问题。但正如我所写,我希望将这个答案放在这里有一些实用性,因为我从来没有找到一个简单的例子来说明如何做到这一点。在这里。

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

    $ brew install redis
    

    然后你运行它

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

    (显然有办法让它在启动时启动。)这是我的服务器代码,main.py

    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')
    

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

    from flask_socketio import SocketIO
    import datetime
    import time    
    
    socketio = SocketIO(message_queue='redis://')    
    
    if __name__ == '__main__':
        while True:
            msg = datetime.datetime.now().strftime("%a, %d %b %Y %H:%M:%S")
            print(msg)
            socketio.emit('message', msg, broadcast=True)
            time.sleep(1)
    

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

    <html>
    <head>
    <title>Listener</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();    
    
        socket.on('message', function(msg) {
            $("#messages").append('<li>'+msg+'</li>');
            console.log('Received message');
        });
    });
    </script>
    <ul id="messages"></ul>
    </body>
    </html>
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-19
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多