Skip to content

🐛 keep onebot11 message loop alive on events before login - #40

Merged
RF-Tar-Railt merged 1 commit into
RF-Tar-Railt:mainfrom
g1331:fix/onebot11-early-event
Oct 23, 2026
Merged

RF-Tar-Railt merged 1 commit into
RF-Tar-Railt:mainfrom
g1331:fix/onebot11-early-event

Conversation

@g1331

@g1331 g1331 commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

问题

OneBot 11 适配器收到 lifecycle.connect / heartbeat 后,用 asyncio.create_task(_login_add()) 异步登记账号,_login_add 要先等 get_login_info 的响应,才把 login 写入 logins。

这段时间里协议端(比如 NapCat)如果已经推来普通事件,message_handle 会走到:

if self_id not in self.adapter.logins:
    logger.warning(f"received event from unknown self_id: {data}")
    return

这里的 return 结束的是整个接收循环,不只是这一条事件。之后连 get_login_info 的 echo 响应也没人处理,账号不会登记:

  • reverse:message_handle 结束后 websocket_server_handler 进入 finally,self.logins[account_id] 因为账号还没写入而抛 KeyError,连接被关闭,等协议端重连后可能再次撞上同样的时序。
  • forward:receiver_task 结束,connection_daemon 转入下一轮重连。

群消息多的账号刚连上时比较容易遇到。

最小复现:用一个假的 WebSocket 先推 lifecycle.connect,在回复 get_login_info 之前推一条群消息事件,再回复 echo。main 上 message_handle 立即退出,logins 为空。

改法

把这处 return 改成 continue:照旧记录 warning 并丢弃这条登录前的事件,循环继续处理后续消息。forward.py 与 reverse.py 中的同一段代码一起修改。

只有 self_id 未登记的分支受影响,账号已登记时的事件处理、echo 响应、心跳和 connect 的逻辑都没有变化。

lifecycle.enable / lifecycle.disable 两处的 return 没有改。按 OneBot 11 的约定,这两个事件只会出现在 HTTP 通信方式下,WebSocket 连接中收到时目前的处理是记录 warning 并结束接收,我不确定这是否有意为之,所以保持原样。

验证

仓库目前没有测试框架,我用未提交到仓库的脚本验证:给 _Connection(reverse)和 OneBot11ForwardAdapter(forward)喂入同一组消息——lifecycle.connect → 群消息事件 → get_login_info 的 echo 响应,等待 0.5 秒后检查。

main 本 PR
reverse message_handle 已退出,logins 为空 仍在运行,logins 含该账号,推送了 login-added
forward message_handle 已退出,logins 为空 仍在运行,logins 含该账号

两种情况下那条登录前的事件都只记录 warning 后被丢弃。

ruff check 通过,black --check 无差异。

@RF-Tar-Railt
RF-Tar-Railt merged commit c692623 into RF-Tar-Railt:main Oct 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants