mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix(feishu): invoke SDK disconnect() directly and surface cleanup failures
This commit is contained in:
parent
54e3f7f3fa
commit
e9ead959b8
@ -548,15 +548,20 @@ public class FeishuChannelAdapter extends AbstractChannelAdapter implements Stre
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭 WebSocket 连接
|
||||
* 关闭 WebSocket 连接。
|
||||
* <p>
|
||||
* 必须主动关闭底层 WebSocket 连接并触发 SDK 的内部清理(停止 pingLoop、
|
||||
* 释放 ExecutorService)。仅置空引用会导致旧连接的 pingLoop 和线程池
|
||||
* 持续运行,造成文件描述符和线程泄漏,最终使新连接无法建立。
|
||||
* <p>
|
||||
* SDK 的 {@code disconnect()} 是 protected 的,无法直接调用。通过反射
|
||||
* 获取内部 {@code conn} 字段并发送 close(1000) 触发 SDK 的
|
||||
* {@code onClosed → disconnect()} 清理链路。
|
||||
* 走 SDK 内部 {@code disconnect()} 这条单一入口完成 cleanup —— 它本身就是
|
||||
* SDK 在 {@code onClosed} 回调里调用的方法,包含
|
||||
* {@code conn.close(1000) → executor.shutdown() → 字段清零} 的全套动作。
|
||||
* 该方法在 SDK 2.6.1 中是 {@code protected},外部需通过反射 + setAccessible
|
||||
* 调用;SDK 2.7.1 起新增了 public {@code close()},届时整段反射可以删除。
|
||||
* <p>
|
||||
* 反射失败(例如未来 SDK 重命名 {@code disconnect})以 WARN 级别记录而非
|
||||
* 静默吞掉,避免泄漏在升级后悄无声息地复发。
|
||||
*/
|
||||
private void stopWebSocket() {
|
||||
cancelSilentDisconnectWatchdog();
|
||||
@ -567,17 +572,14 @@ public class FeishuChannelAdapter extends AbstractChannelAdapter implements Stre
|
||||
}
|
||||
if (wsClient != null) {
|
||||
try {
|
||||
// 反射获取 protected conn 字段,发送 close(1000) 触发 SDK 清理
|
||||
var connField = wsClient.getClass().getDeclaredField("conn");
|
||||
connField.setAccessible(true);
|
||||
Object conn = connField.get(wsClient);
|
||||
if (conn != null) {
|
||||
// conn 是 OkHttp WebSocket,close(1000) 会触发 onClosed → disconnect()
|
||||
var closeMethod = conn.getClass().getMethod("close", int.class, String.class);
|
||||
closeMethod.invoke(conn, 1000, "client closed");
|
||||
}
|
||||
var disconnect = wsClient.getClass().getDeclaredMethod("disconnect");
|
||||
disconnect.setAccessible(true);
|
||||
disconnect.invoke(wsClient);
|
||||
} catch (NoSuchMethodException e) {
|
||||
log.warn("[feishu] SDK Client.disconnect() not found — WebSocket cleanup skipped, "
|
||||
+ "leak may recur until SDK API is re-verified: {}", e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.debug("[feishu] Error during WebSocket disconnect: {}", e.getMessage());
|
||||
log.warn("[feishu] WebSocket disconnect failed: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
wsClient = null;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user