在 Flask-SocketIO 多处理中将套接字作为参数传递

Passing socket as an argument in Flask-SocketIO multiprocessing

我正在尝试让 Flask-SocketIO 服务器与多处理一起工作。服务器在没有多处理的情况下工作正常。我需要在通过访问路由调用的函数内发出 SocketIO 消息。以前,我通过将 socketio 作为参数传递给函数,然后使用 socketio.emit() 来完成此操作,效果很好。不幸的是,当我使用 pool.apply() 将函数添加到池中时,我得到 TypeError: cannot serialize 'greenlet.greenlet' object。如果我不通过套接字,它可以工作,但显然我没有获得我需要的套接字功能。是什么导致了这个错误,我该如何纠正它?我没有使用 gunicorn 或 eventlet 或 gevent 或其他任何东西。

我的简化代码:

def requester(user, socket):

    socket.emit('hello')
    # do some stuff with requests and databases
    socket.emit('goodbye')

def main():

    app = Flask(__name__,
                static_url_path='',
                static_folder='dist',
                template_folder='dist')

    socketio = SocketIO(app)

    pool = multiprocessing.Pool(16)

    @app.route('/addname', methods=['POST'])
    def add_name:
        pool.apply(requester, args=(request.json['user'], socketio))
        return request.json['user'], 201

    socketio.run(app, host='0.0.0.0', port=8000)

if __name__ == '__main__':
    main()

I'm not using gunicorn or eventlet or gevent or anything else.

您显然正在使用基于 greenlet 的框架。异步框架的选择是自动的,因此通过在您的 virtualenv 上安装 eventlet 或 gevent 可以使用 greenlets。如果您不想使用这些,请确保没有安装 eventlet 或 gevent。

I am trying to get a Flask-SocketIO server working with multiprocessing.

这是行不通的,因为 Socket.IO 是一个有状态的服务器,您不能仅通过 运行 个工作进程进行扩展。

有关从辅助进程发送到客户端的推荐方法,请参阅 emitting from an external process 上的文档。