使用Python signalrcore调用SignalR订阅账户时遇Hub未运行错误
SignalR Python客户端订阅账户报错排查
问题现象
使用Python的signalrcore客户端集成实时交易数据Feed,已成功连接Hub,账户查询API也能正常工作,但调用hub.send("SubscribeAccount", [account_id])订阅账户时持续报错:
ERROR - Error subscribing to account (attempt 1): Hub is not running you cand send messages
控制台完整输出:
INFO - Bearer token loaded from config manager INFO - Attempting to connect (attempt 1/3) INFO - Starting connection... INFO - Connection opened INFO - Close message received from server INFO - Connection established INFO - Connection established successfully INFO - Searching for accounts... INFO - Found 1 accounts INFO - Account found: S1MAY1613963393 (ID: 7873648) INFO - Attempting to subscribe to account 7873648 (attempt 1) ERROR - Error subscribing to account (attempt 1): Hub is not running you cand send messages ...
环境信息
- Python 3.10
- signalrcore 0.10.1
- 服务器URL:
wss://rtc.topstepx.com/hubs/user(通过Authorizationheader携带Bearer令牌)
已尝试的解决措施
- 在发送订阅请求前添加延迟
- 确认
hub._connected为True - 验证
/api/Account/search返回有效账户 - 订阅前手动重连
- 在
on_open后立即订阅和短延迟后订阅
相关代码片段
连接初始化代码:
self._connection = HubConnectionBuilder()\ .with_url( self.USER_HUB, options={ "access_token_factory": lambda: self._bearer_token, "skip_negotiation": True, "transport": "websockets" })\ .build() self._connection.on_open(self._on_open) self._connection.on_close(self._on_close) self._connection.on_error(self._on_error) self._connection.start() await asyncio.wait_for(self._connection_ready.wait(), timeout=5)
订阅调用:
await hub.subscribe_account(account_id)
subscribe_account内部实现:
# Inside `subscribe_account` self._connection.send("SubscribeAccount", [account_id])
问题解答
错误含义
这个错误字面意思是客户端认为当前Hub连接未处于运行状态,因此拒绝发送消息,注意错误里的"cand"是拼写错误,实际应为"can't"。
问题归属
大概率是客户端配置/状态判断逻辑的问题,而非服务端问题。原因如下:
- 已成功连接Hub、正常调用账户查询API,说明服务端基础通信链路正常;
- 控制台出现
Close message received from server后又提示Connection established,存在连接状态时序异常——客户端认为连接已建立,但内部状态未正确同步。
调试与解决思路
修正状态等待逻辑
- 检查
_on_open回调是否正确触发了self._connection_ready.set(),如果回调未执行,wait()超时后代码会继续执行,但此时连接实际未就绪; - 替代方案:直接监听连接状态,确认进入
CONNECTED状态再发送消息:from signalrcore.connection_state import ConnectionState while self._connection.state != ConnectionState.CONNECTED: await asyncio.sleep(0.1)
- 检查
排查连接异常根源
- 在
_on_close和_on_error回调中打印详细信息,定位服务端主动关闭连接的原因:def _on_close(self): print(f"Connection closed, reason: {self._connection.close_reason}") self._connection_ready.clear() def _on_error(self, error): print(f"Connection error: {error}") - 验证Bearer令牌权限:虽然账户API可用,但SignalR连接的令牌可能缺少订阅账户的权限,或存在过期/刷新异常。
- 在
修正异步场景下的send调用
- 异步环境中需使用
send_async替代send,避免状态判断错误:await self._connection.send_async("SubscribeAccount", [account_id])
- 异步环境中需使用
调整协商模式
- 尝试移除
skip_negotiation: True配置,部分SignalR服务器要求必须协商才能建立有效连接:options={ "access_token_factory": lambda: self._bearer_token, "transport": "websockets" }
- 尝试移除
降级signalrcore版本
- 0.10.1版本可能存在状态同步bug,尝试降级到0.9.3或0.8.2版本测试是否解决问题。
内容的提问来源于stack exchange,提问作者A-laz
相关产品推荐
相关产品推荐

