【问题标题】:Passing socket as an argument in Flask-SocketIO multiprocessing在 Flask-SocketIO 多处理中将套接字作为参数传递
【发布时间】:2020-03-29 02:44:15
【问题描述】:

我正在尝试让 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-multiprocessing flask-socketio


    【解决方案1】:

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

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

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

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

    请参阅emitting from an external process 上的文档,了解从辅助进程向客户端发出的推荐方法。

    【讨论】:

    • 谢谢。我不打算使用 eventlet,但它必须仍然在我的系统上运行,因为之前尝试让它与 gunicorn/eventlet 一起工作。我现在正在考虑使用 Redis 作为队列并从那里发出,但是有更好的方法吗?我尝试了几种并发方法,但每一种都遇到了问题。
    • 该方法在我链接的文档部分中进行了描述。您不会为此使用 Redis,您只需要运行 Redis(或其他 msg 队列)以供 Socket.IO 包使用。如文档中所述,您仍将使用 Python 发射函数来发射。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    相关资源
    最近更新 更多