ErisPulse-QQBotAdapter 4.0.1__tar.gz → 4.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/ErisPulse_QQBotAdapter.egg-info/PKG-INFO +1 -1
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/PKG-INFO +1 -1
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/QQBotAdapter/WebSocket.py +58 -30
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/pyproject.toml +1 -1
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/ErisPulse_QQBotAdapter.egg-info/SOURCES.txt +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/ErisPulse_QQBotAdapter.egg-info/dependency_links.txt +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/ErisPulse_QQBotAdapter.egg-info/entry_points.txt +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/ErisPulse_QQBotAdapter.egg-info/top_level.txt +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/QQBotAdapter/Converter.py +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/QQBotAdapter/Core.py +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/QQBotAdapter/__init__.py +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/README.md +0 -0
- {erispulse_qqbotadapter-4.0.1 → erispulse_qqbotadapter-4.0.2}/setup.cfg +0 -0
|
@@ -30,6 +30,8 @@ class QQBotWebSocket:
|
|
|
30
30
|
self._reconnect_count = 0
|
|
31
31
|
self._max_reconnect = 50
|
|
32
32
|
self._closing = False
|
|
33
|
+
self._reconnect_lock = asyncio.Lock()
|
|
34
|
+
self._reconnect_task: Optional[asyncio.Task] = None
|
|
33
35
|
|
|
34
36
|
async def connect(self):
|
|
35
37
|
gateway_url = self.adapter.config.get("gateway_url", "wss://api.sgroup.qq.com/websocket/")
|
|
@@ -64,7 +66,7 @@ class QQBotWebSocket:
|
|
|
64
66
|
|
|
65
67
|
except Exception as e:
|
|
66
68
|
self.adapter.logger.error(f"WebSocket 连接失败: {e}")
|
|
67
|
-
|
|
69
|
+
self._schedule_reconnect()
|
|
68
70
|
|
|
69
71
|
async def _identify(self):
|
|
70
72
|
token = await self.adapter._ensure_token()
|
|
@@ -109,7 +111,7 @@ class QQBotWebSocket:
|
|
|
109
111
|
pass
|
|
110
112
|
except Exception as e:
|
|
111
113
|
self.adapter.logger.error(f"心跳循环异常: {e}")
|
|
112
|
-
|
|
114
|
+
self._schedule_reconnect()
|
|
113
115
|
|
|
114
116
|
async def _listen(self):
|
|
115
117
|
try:
|
|
@@ -122,13 +124,13 @@ class QQBotWebSocket:
|
|
|
122
124
|
self.adapter.logger.warning(f"WebSocket 关闭: {msg.type}")
|
|
123
125
|
break
|
|
124
126
|
except asyncio.CancelledError:
|
|
125
|
-
|
|
127
|
+
return
|
|
126
128
|
except Exception as e:
|
|
127
129
|
self.adapter.logger.error(f"监听异常: {e}")
|
|
128
130
|
finally:
|
|
129
131
|
self._connected = False
|
|
130
|
-
if not self._closing
|
|
131
|
-
|
|
132
|
+
if not self._closing:
|
|
133
|
+
self._schedule_reconnect()
|
|
132
134
|
|
|
133
135
|
async def _handle_message(self, data: dict):
|
|
134
136
|
op = data.get("op")
|
|
@@ -163,50 +165,68 @@ class QQBotWebSocket:
|
|
|
163
165
|
|
|
164
166
|
elif op == self.OP_RECONNECT:
|
|
165
167
|
self.adapter.logger.warning("收到 Reconnect 指令,重新连接")
|
|
166
|
-
|
|
168
|
+
self._schedule_reconnect()
|
|
167
169
|
|
|
168
170
|
elif op == self.OP_INVALID_SESSION:
|
|
169
171
|
self.adapter.logger.warning("会话无效,重新 Identify")
|
|
170
172
|
self.session_id = None
|
|
171
173
|
self.seq = None
|
|
172
|
-
|
|
174
|
+
self._schedule_reconnect()
|
|
173
175
|
|
|
174
176
|
elif op == self.OP_HELLO:
|
|
175
177
|
data_inner = d if d else {}
|
|
176
178
|
self.heartbeat_interval = data_inner.get("heartbeat_interval", 45000)
|
|
177
179
|
|
|
180
|
+
def _schedule_reconnect(self):
|
|
181
|
+
if self._closing:
|
|
182
|
+
return
|
|
183
|
+
if self._reconnect_task and not self._reconnect_task.done():
|
|
184
|
+
return
|
|
185
|
+
self._reconnect_task = asyncio.create_task(self._reconnect())
|
|
186
|
+
|
|
178
187
|
async def _reconnect(self):
|
|
179
188
|
if self._closing:
|
|
180
189
|
return
|
|
181
190
|
|
|
182
|
-
|
|
183
|
-
self.
|
|
184
|
-
try:
|
|
185
|
-
await self.heartbeat_task
|
|
186
|
-
except asyncio.CancelledError:
|
|
187
|
-
pass
|
|
188
|
-
self.heartbeat_task = None
|
|
191
|
+
async with self._reconnect_lock:
|
|
192
|
+
self._connected = False
|
|
189
193
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
+
if self.heartbeat_task:
|
|
195
|
+
self.heartbeat_task.cancel()
|
|
196
|
+
try:
|
|
197
|
+
await self.heartbeat_task
|
|
198
|
+
except asyncio.CancelledError:
|
|
199
|
+
pass
|
|
200
|
+
self.heartbeat_task = None
|
|
194
201
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
if self.listen_task:
|
|
203
|
+
self.listen_task.cancel()
|
|
204
|
+
try:
|
|
205
|
+
await self.listen_task
|
|
206
|
+
except asyncio.CancelledError:
|
|
207
|
+
pass
|
|
208
|
+
self.listen_task = None
|
|
198
209
|
|
|
199
|
-
|
|
200
|
-
|
|
210
|
+
self._reconnect_count += 1
|
|
211
|
+
if self._reconnect_count > self._max_reconnect:
|
|
212
|
+
self.adapter.logger.error("已达到最大重连次数,停止重连")
|
|
213
|
+
return
|
|
201
214
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
except Exception:
|
|
206
|
-
pass
|
|
215
|
+
wait_time = min(5 * (2 ** min(self._reconnect_count, 6)), 300)
|
|
216
|
+
self.adapter.logger.warning(f"{wait_time}秒后尝试第 {self._reconnect_count} 次重连")
|
|
217
|
+
await asyncio.sleep(wait_time)
|
|
207
218
|
|
|
208
|
-
|
|
209
|
-
|
|
219
|
+
if self._closing:
|
|
220
|
+
return
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
if self.ws and not self.ws.closed:
|
|
224
|
+
await self.ws.close()
|
|
225
|
+
except Exception:
|
|
226
|
+
pass
|
|
227
|
+
|
|
228
|
+
gateway_url = self.adapter.config.get("gateway_url", "wss://api.sgroup.qq.com/websocket/")
|
|
229
|
+
await self._connect(gateway_url)
|
|
210
230
|
|
|
211
231
|
async def start_token_refresh(self):
|
|
212
232
|
self._token_refresh_task = asyncio.create_task(self._token_refresh_loop())
|
|
@@ -226,6 +246,14 @@ class QQBotWebSocket:
|
|
|
226
246
|
self._closing = True
|
|
227
247
|
self._connected = False
|
|
228
248
|
|
|
249
|
+
if self._reconnect_task:
|
|
250
|
+
self._reconnect_task.cancel()
|
|
251
|
+
try:
|
|
252
|
+
await self._reconnect_task
|
|
253
|
+
except asyncio.CancelledError:
|
|
254
|
+
pass
|
|
255
|
+
self._reconnect_task = None
|
|
256
|
+
|
|
229
257
|
if self._token_refresh_task:
|
|
230
258
|
self._token_refresh_task.cancel()
|
|
231
259
|
try:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|