Socket.io客户端连接服务器触发AttributeError错误求助
解决Socket.io异步服务器中'_asyncio.Task'对象无'is_alive'属性的错误
错误详情
Client connected: 3uRG6PtVuta3wHsbAAAD message async handler error Traceback (most recent call last): File "/home/ahmed/.local/lib/python3.10/site-packages/engineio/async_server.py", line 483, in run_async_handler return await self.handlers[event](*args) File "/home/ahmed/.local/lib/python3.10/site-packages/socketio/async_server.py", line 669, in _handle_eio_message await self._handle_connect(eio_sid, pkt.namespace, pkt.data) File "/home/ahmed/.local/lib/python3.10/site-packages/socketio/async_server.py", line 552, in _handle_connect success = await self._trigger_event( File "/home/ahmed/.local/lib/python3.10/site-packages/socketio/async_server.py", line 638, in _trigger_event ret = handler(*args) File "/home/ahmed/PycharmProjects/decimal-trade/prices.py", line 27, in connect if not thread.is_alive(): AttributeError: '_asyncio.Task' object has no attribute 'is_alive'
问题根源
- 你初始化了
thread = Thread(),但sio.start_background_task()在异步模式下返回的是asyncio.Task对象,而非Thread实例,因此调用is_alive()会触发属性错误。 - 同步的
requests.get()会阻塞异步事件循环,拖慢服务器响应速度。 - 异步Socket.io服务器的事件处理器(如connect)需定义为异步函数(
async def),同步函数会导致调用逻辑冲突。
修复方案
修改后的服务器代码
from aiohttp import web, ClientSession import socketio sio = socketio.AsyncServer(async_mode='aiohttp', logger=True, engineio_logger=True, cors_allowed_origins='*') app = web.Application() sio.attach(app) # 初始化为None,替代原Thread对象 price_task = None url = 'https://financialmodelingprep.com/api/v3/stock/real-time-price?apikey=yfmtiz4PGwIlCalGtRjsLcrQ9rF6NAHt' async def server(request): return web.Response(text='Server Running...') async def getPrices(): async with ClientSession() as session: while True: # 用异步HTTP请求替代同步requests async with session.get(url) as resp: data = await resp.json() data = data['stockList'] await sio.emit('stocks', {'data': data}, namespace='/prices') await sio.sleep(60) # 将connect处理器改为异步函数 @sio.on('connect', namespace='/prices') async def connect(sid, environ): global price_task print('Client connected: ', sid) # 判断异步任务是否未启动或已完成 if price_task is None or price_task.done(): price_task = sio.start_background_task(getPrices) @sio.on('disconnect', namespace='/prices') def disconnect(sid): print('Client disconnected: ', sid) app.router.add_static('/static', 'static') app.router.add_get('/', server) if __name__ == '__main__': web.run_app(app, host='127.0.0.1', port=8080)
关键修改点
- 异步HTTP请求:用
aiohttp.ClientSession替代同步requests,避免阻塞事件循环。 - 任务类型修正:将
thread变量改为price_task,初始化为None,不再依赖Thread对象。 - 异步事件处理器:把
connect函数改为async def,适配异步Socket.io服务器的调用逻辑。 - 任务状态判断:用
price_task is None or price_task.done()替代is_alive(),正确判断异步任务的运行状态。
React端代码
无需修改,保持原代码即可:
import { io } from 'socket.io-client'; const URL_ = 'http://127.0.0.1:8080/prices'; export const socket = io.connect(URL_, { cors: { origin: 'http://127.0.0.1:8080', credentials: true, } });
内容的提问来源于stack exchange,提问作者Ahmed B
相关产品推荐
相关产品推荐

