我有一个在多个容器上运行的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!"}]
答案 0 :(得分:0)
不幸的是,目前没有任何机制可以执行您的要求。
我认为您基本上有两种方法可以解决此问题:
始终运行来自主服务器的发射。如果需要从辅助进程中进行发射,请使用IPC机制通知服务器,以便它可以代表其运行发射。现在您可以使用回调了。
忽略回调,而是让客户端通过发送回服务器来确认事件的接收。
顺便说一句,为辅助进程添加回调支持应该不会很困难。我本人从来不需要该功能,而您是第一个问这个功能的人。也许我应该在某个时候研究一下。
编辑:经过一番思考,我想到了第三个选项:
您可以将外部进程作为客户端连接到服务器,而不是使用“仅发送”选项。如果此过程是客户端,则它可以向服务器发出事件,服务器再可以将事件中继到外部客户端。当客户端回复服务器时,服务器可以再次将响应中继到外部进程,该外部进程不是另一个客户端,并且具有完整的发送和接收功能。