Почему браузер не обновляется в реальном времени с помощью Flask socketIO? - PullRequest
0 голосов
/ 17 сентября 2018

Я новичок в 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. Кажется зависает - в нижней части браузера написано «Ожидание кэша» или «Ожидание локального хоста». Может кто-нибудь выяснить, что я делаю не так? Большое спасибо заранее!

1 Ответ

0 голосов
/ 24 сентября 2018

ОК, я отвечаю на это всем, кто сталкивается с этой проблемой, должен иметь внешний процесс, отправляющий сообщения в браузер, используя Flask и socketIO. Я потратил много времени на поиск в Google и Stackoverflow, и я так и не нашел по-настоящему простого, чистого примера, так что здесь он в меру своих возможностей.

Это то, что я хотел: использовать Python, Flask и SocketIO и иметь внешний процесс, выполняющий отправку сообщений, которые будут отображаться в браузере. Моим первым ударом было то, что я написал в виде вопроса, который должен был породить поток с внешним процессом. Я закончил тем, что сделал другую программу на Python внешним процессом, что для моего приложения, робота-сенсора, на самом деле лучше. Итак, моя вина, я не отвечаю на мой вопрос точно . Но, как я уже писал, я надеюсь, что здесь есть какая-то полезность, потому что я так и не нашел простой пример того, как это сделать. Вот оно.

Я думаю, что существенная проблема заключается в том, что вам нужно какое-то распределение нагрузки, чтобы внешний процесс отправлял сообщения через socketio, поскольку код не знает, получает ли он сообщения от 1 программы или 10 000. Мне показалось, что проще всего было использовать Redis. Таким образом, вы должны иметь повторный запуск и запуск, когда код работает. На Mac с Homebrew вы устанавливаете 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, установите redis с помощью https://www.alibabacloud.com/blog/how-to-install-and-configure-redis-server-on-debian-9_472211. Это просто безумно легко. Наслаждайтесь 10

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...