【问题标题】:Flask-socketio doesn't recieve message from clientFlask-socketio 没有收到来自客户端的消息
【发布时间】:2020-07-23 15:20:58
【问题描述】:

我正在尝试编写一个基本的 Socket.io 程序,其中 python 客户端(python-socketio[asyncio_client] 4.6.0)向烧瓶服务器(使用 Flask-SocketIO 4.3.1 和 eventlet)发出一条字符串消息.

客户端似乎可以正确连接并发送消息,但在 Flask 服务器上看不到输出。

服务器代码:

from flask import Flask
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@socketio.on('connect')
def test_connect():
    print('connected')


@socketio.on('disconnect')
def test_disconnect():
    print('Client disconnected')

@socketio.on('message')
def handle_message(msg):
    print('Recieved',msg)

@socketio.on('json')
def handle_json(json):
    print(str(json))

if __name__ == '__main__':
    socketio.run(app,debug=True)

客户端代码:

    import asyncio
    import socketio
    
    sio = socketio.AsyncClient()
    
    @sio.event
    def connect():
        print('connection established')
    
    @sio.event
    def disconnect():
        print('disconnected from server')
    
    async def main():
        await sio.connect('http://localhost:5000')
        await sio.emit('message',data='detection')
        print('message sent')
        await sio.disconnect()
    
    if __name__ == '__main__':
        asyncio.run(main())

服务器输出:

PS C:\Users\daksh\sih\sihPython> python .\test_socketio.py
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 101-561-255
(16664) wsgi starting up on http://127.0.0.1:5000
(16664) accepted ('127.0.0.1', 59497)
connected
127.0.0.1 - - [23/Jul/2020 20:38:42] "GET /socket.io/?transport=polling&EIO=3&t=1595516920.71801 HTTP/1.1" 200 367 0.004934
Client disconnected
127.0.0.1 - - [23/Jul/2020 20:38:42] "GET /socket.io/?transport=websocket&EIO=3&sid=88790300120f4b899e019ae7cc16ee87&t=1595516922.7757218 HTTP/1.1" 200 0 0.010027

客户端输出:

PS C:\Users\daksh\sih\sihPython> python .\socketio-client.py
connection established
message sent

来自handle_message() 的打印语句在服务器输出中丢失。

我已经浏览了多个在线教程,并且尝试过使用和不使用命名空间。一直没搞清楚是什么问题。

感谢任何帮助。

(我在 Windows 10 上使用 Python 3.8.3)

更新:如果我将客户端代码更改为使用socketio.Client() 而不是AsyncClient(),它会起作用,但是我需要客户端使用AsyncClient 进行连接。

【问题讨论】:

    标签: python-3.x flask flask-socketio python-socketio


    【解决方案1】:

    问题是你的异步客户端显然是异步的,你不能只是发送和退出,因为你没有给支持 Socket.IO 协议的后台任务时间去做他们的事情。

    这是一个更强大的客户端版本,它让事件在退出之前通过:

    import asyncio
    import socketio
    
    sio = socketio.AsyncClient()
    
    @sio.event
    async def connect():
        print('connection established')
        await sio.emit('message',data='detection', callback=done)
        print('message sent')
    
    @sio.event
    def disconnect():
        print('disconnected from server')
    
    async def done():
        await sio.disconnect()
    
    async def main():
        await sio.connect('http://localhost:5000')
        await sio.wait()
    
    if __name__ == '__main__':
        asyncio.run(main())
    

    这里的技巧是在发射时使用回调。调用回调时,您确定消息已传递,因此此时断开连接是安全的。

    【讨论】:

    • 感谢@Miguel 的示例。使用来自 OP 的服务器代码和您的客户端代码,我收到一个错误,其中包含消息 raise exceptions.BadNamespaceError( socketio.exceptions.BadNamespaceError: / is not a connected namespace. Unclosed client session,并以 RuntimeError: Event loop is closed 结尾。我不知道如何让一个简单的例子工作。
    • @fffrost 是的,这个答案中的代码还有一个我当时没有看到的问题。连接调用也是异步的,您必须等到连接处理程序被调用才能发出。我现在已将发射移至连接处理程序以解决此问题。
    猜你喜欢
    • 2021-04-08
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 2020-10-15
    相关资源
    最近更新 更多