Flask-SocketIO在uWSGI上的使用

3
我有一个Flask-SocketIO应用程序。
(venv) ubuntu@ip-172-31-18-21:~/code$ more app.py
from flask_socketio import SocketIO, send, emit
from flask import Flask, render_template, url_for, copy_current_request_context
from time import sleep
from threading import Thread, Event

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'

socketio = SocketIO(app, async_mode='gevent')

thread = Thread()
thread_stop_event = Event()

def firstFunction():
    print("*** First function")

def backgroundTask():
    while not thread_stop_event.isSet():
        socketio.emit('bg-socketio', {'data':'background-data'}, namespace='/', broadcast=True)
        socketio.sleep(2)

def startBackgroundTask():
    global thread

    if not thread.is_alive():
        thread = socketio.start_background_task(backgroundTask)

@app.route('/')
def main():
    return render_template('index.html', title='SocketIO')  

@socketio.on('connect_event', namespace='/')
def handle_message_client_connected(message):
    print("*** Client connected")
    emit('c-socketio', {'data':' you connected!'}, namespace='/') 

if __name__ == '__main__':
    firstFunction()
    startBackgroundTask()
    socketio.run(app, host='0.0.0.0', port=5000) 

我希望在应用程序启动时运行firstFunction()和startBackgroundTask()。

在uWSGI上,运行此操作的最佳实践是什么?我一直在尝试这样做,但没有成功,一直收到错误。 https://flask-socketio.readthedocs.io/en/latest/#uwsgi-web-server

错误: * 运行 gevent 循环引擎 [addr:0x5561d3f745a0] * 糟糕!工作进程 1 (pid:13772) 已经死掉了 :( 尝试重启... 工作进程重启太快了!!! 我必须稍微休息一下(2秒钟)... 重新生成 uWSGI 工作进程 1 (新 pid:13773)

我还尝试了这个方法

uwsgi --socket 0.0.0.0:5000 --protocol=http --enable-threads -w wsgi:app

(venv) ubuntu@ip-172-31-18-21:~/code$ more wsgi.py
from uapp import app

if __name__ == "__main__":
    app.run()

将uapp.py更改为

if __name__ == '__main__':
    firstFunction()
    startBackgroundTask()
    app.run(host='0.0.0.0', port=5000)

但这并不会运行firstFunction()或startBackgroundTask()

我基本上被卡住了,正在寻找一些建议。


你考虑过使用 APScheduler 模块吗? - ngShravil.py
尝试了 APScheduler,虽然能够让一些东西运行起来,但 SocketIO 发送的消息会延迟约 25 秒。现在 'socketio.emit' 命令位于 backgroundTask() 中,该任务被安排每秒运行一次,使用 'sched.add_job(backgroundTask,'interval',seconds=1)'。 - user8865059
你能否在原始帖子中更新相同的代码? - ngShravil.py
1
你有没有阅读关于在uWSGI上运行Flask-SocketIO的文档?你的uwsgi启动命令完全错误,而且你强制使用async_mode='gevent',这在uWSGI上不起作用。 - Miguel Grinberg
2个回答

0

使用'pip install gevent'安装的gevent 20.5.2无法正常工作。更改为gevent==1.4.0后,uWSGI可以按预期启动。


0

对你的问题的简单答案是改变这个:

if __name__ == '__main__':
    firstFunction()
    startBackgroundTask()
    app.run(host='0.0.0.0', port=5000)

转换为:

firstFunction()
startBackgroundTask()

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

不过,您还需要解决其他一些问题。

async_mode 变量设置为 gevent,但您正在使用 uWSGI 作为服务器。要么将其更改为 gevent_uwsgi,要么删除它,以便在运行时自动设置。

在文档中显示了使用 uWSGI 启动 Flask-SocketIO 应用程序的命令:

uwsgi --http :5000 --gevent 1000 --http-websockets --master --wsgi-file app.py --callable app

你还需要安装gevent


我已经进行了更改,但是出现了该死的!worker 1错误。Gevent已安装:gevent==20.5.2 gevent-websocket==0.10.1 python-socketio==4.6.0uwsgi版本为2.0.18,在Ubuntu 18.0.4上运行。我还删除了firstFunction()和startBackgroundTask(),所以它只是flask-socketio。 - user8865059
我选择设置新的EC2 t2.micro Ubuntu 18.04实例以开始全新的工作。我正在按照https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-0中的步骤1-3,然后按照https://flask-socketio.readthedocs.io/en/latest/进行flask-SocketIO,并像那里所示执行uWSGI。立即出现“DAMN!worker 1(pid:30699)已死:(尝试重生...worker respawning too fast !!! i have to sleep a bit (2 seconds)...”错误。在EC2 t2.micro实例上这样做有什么问题吗?感谢任何建议。 - user8865059
你修复了 async_mode 参数吗? - Miguel Grinberg
是的,我做了。从flask导入Flask和render_template 从flask_socketio导入SocketIOapp = Flask(name) app.config['SECRET_KEY'] = 'secret!' socketio = SocketIO(app)if name == 'main': app.run(host='0.0.0.0', port=5000) - user8865059
然后在日志中寻找其他线索,不确定还有什么建议。如果您在问题中添加完整的日志,我很乐意帮忙查看。 - Miguel Grinberg
感谢您的帮助,可以看一下我上面的回答。 - user8865059

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接