我有一个在 flask 上运行的flask-socketio服务器,使用redis作为消息队列。我想确保来自外部进程的排放在100%的时间内达到目标,或者知道它们何时失败。

当进程A向连接到进程B的套接字发出事件时,该事件通过消息队列到达进程B,再传递给客户端。有什么办法可以拦截进程B上的传出发射?理想情况下,我会在几秒钟后使用一个工作程序来检查消息是否到达客户端(通过从客户端发出的确认事件)或是否会再次发出。

此代码在进程A上运行:

@app.route('/ex')
def ex_route():
    socketio.emit('external', {'text': f'sender: {socket.gethostname()}, welcome!'}, room='some_room')
    return jsonify(f'sending message to room "some_room" from {socket.gethostname()}')

这是过程A的输出
INFO:socketio.server:emitting event "external" to some_room [/]
INFO:geventwebsocket.handler:127.0.0.1 - - [2019-01-11 13:33:44] "GET /ex HTTP/1.1" 200 177 0.003196

这是流程B的输出
INFO:engineio.server:9aab2215a0da4816a45e3fdc1e449fce: Sending packet MESSAGE data 2["external",{"text":"sender: *******, welcome!"}]

最佳答案

不幸的是,目前没有任何机制可以执行您的要求。

我认为您基本上有两种方法可以解决此问题:

  • 始终运行来自主服务器的发射。如果需要从辅助进程中进行发射,请使用IPC机制通知服务器,以便它可以代表其运行发射。现在,您可以使用回调了。
  • 忽略回调,而是让客户端通过发回服务器来确认事件的接收。

  • 顺便说一句,为辅助进程添加回调支持应该不会很困难。我本人从来不需要该功能,而您是第一个问这个功能的人。也许我应该在某个时候研究一下。

    编辑:经过一番思考,我想到了第三个选项:

    您可以将外部进程作为客户端连接到服务器,而不是使用“仅发送”选项。如果此过程是客户端,则它可以向服务器发出事件,服务器再可以将事件中继到外部客户端。当客户端答复服务器时,服务器可以再次将响应中继到外部进程,该外部进程不是另一个客户端,并且具有完整的发送和接收功能。

    09-20 17:58