首页 > 解决方案 > 在 Flask-SocketIO 多处理中将套接字作为参数传递

问题描述

我正在尝试让 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()

标签: python-multiprocessingflask-socketio

解决方案


我没有使用 gunicorn 或 eventlet 或 gevent 或其他任何东西。

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

我正在尝试让 Flask-SocketIO 服务器与多处理一起工作。

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

请参阅有关从外部进程发出的文档,以了解从辅助进程向客户端发出的推荐方法。


推荐阅读