mqttxx 3.1.2__py3-none-any.whl → 3.2.1__py3-none-any.whl
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.
- mqttxx/__init__.py +2 -5
- mqttxx/client.py +144 -233
- mqttxx/events.py +45 -26
- mqttxx/protocol.py +45 -149
- mqttxx/rpc.py +48 -29
- {mqttxx-3.1.2.dist-info → mqttxx-3.2.1.dist-info}/METADATA +74 -53
- mqttxx-3.2.1.dist-info/RECORD +12 -0
- mqttxx/conventions.py +0 -148
- mqttxx-3.1.2.dist-info/RECORD +0 -13
- {mqttxx-3.1.2.dist-info → mqttxx-3.2.1.dist-info}/LICENSE +0 -0
- {mqttxx-3.1.2.dist-info → mqttxx-3.2.1.dist-info}/WHEEL +0 -0
- {mqttxx-3.1.2.dist-info → mqttxx-3.2.1.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mqttxx
|
|
3
|
-
Version: 3.1
|
|
3
|
+
Version: 3.2.1
|
|
4
4
|
Summary: 基于 aiomqtt 的高级 MQTT 客户端和 RPC 框架
|
|
5
5
|
Author: MQTTX Team
|
|
6
6
|
License: MIT
|
|
@@ -12,13 +12,14 @@ Requires-Dist: loguru >=0.7.0
|
|
|
12
12
|
Provides-Extra: dev
|
|
13
13
|
Requires-Dist: pytest ; extra == 'dev'
|
|
14
14
|
Requires-Dist: pytest-asyncio ; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest-rich ; extra == 'dev'
|
|
15
16
|
Requires-Dist: ruff ; extra == 'dev'
|
|
16
17
|
Requires-Dist: build ; extra == 'dev'
|
|
17
18
|
Requires-Dist: twine ; extra == 'dev'
|
|
18
19
|
|
|
19
20
|
# MQTTX
|
|
20
21
|
|
|
21
|
-
[](https://pypi.org/project/mqttxx/)
|
|
22
23
|
[](https://www.python.org/downloads/)
|
|
23
24
|
[](LICENSE)
|
|
24
25
|
|
|
@@ -34,7 +35,6 @@ Requires-Dist: twine ; extra == 'dev'
|
|
|
34
35
|
- ✅ **Event Channel** - 高吞吐事件广播,支持通配符订阅
|
|
35
36
|
- ✅ **TLS/SSL 支持** - 安全连接、双向认证
|
|
36
37
|
- ✅ **完善异常系统** - 统一错误码、清晰的异常层次
|
|
37
|
-
- ✅ **可插拔编解码器** - 支持 JSON/MessagePack/Protobuf 等自定义协议
|
|
38
38
|
- ✅ **生产级可靠性** - 修复所有 P0 缺陷(任务泄漏、资源泄漏、并发竞态)
|
|
39
39
|
|
|
40
40
|
---
|
|
@@ -50,11 +50,12 @@ Requires-Dist: twine ; extra == 'dev'
|
|
|
50
50
|
- [传统 RPC](#4-rpc-基础用法传统模式)
|
|
51
51
|
- [RPC 权限控制](#5-rpc-权限控制)
|
|
52
52
|
- [TLS/SSL 和认证](#6-tlsssl-和认证)
|
|
53
|
+
- [架构与实现](#架构与实现)
|
|
53
54
|
- [API 速查](#api-速查)
|
|
54
55
|
- [配置对象](#配置对象)
|
|
55
56
|
- [异常系统](#异常系统)
|
|
56
57
|
- [RPC 消息协议](#rpc-消息协议)
|
|
57
|
-
- [版本变更](
|
|
58
|
+
- [版本变更](#版本变更)
|
|
58
59
|
- [开发](#开发)
|
|
59
60
|
- [示例项目](#示例项目)
|
|
60
61
|
- [常见问题](#常见问题)
|
|
@@ -72,47 +73,23 @@ MQTTX 遵循严格的分层架构,确保职责清晰、代码简洁、易于
|
|
|
72
73
|
- 不导入 `json` 或 `protocol` 模块
|
|
73
74
|
- 不理解消息内容
|
|
74
75
|
- `publish()` 只接受 `bytes`
|
|
75
|
-
- `
|
|
76
|
+
- `subscribe()` handler 接收 `bytes`
|
|
76
77
|
|
|
77
78
|
### 2. Protocol(协议层)
|
|
78
|
-
-
|
|
79
|
+
- **职责**:定义消息格式和 JSON 编解码
|
|
79
80
|
- **核心**:
|
|
80
|
-
- `encode()` 方法:object → bytes
|
|
81
|
-
- `decode()` 方法:bytes → object
|
|
82
|
-
- JSON
|
|
81
|
+
- `encode()` 方法:object → bytes(使用 JSON)
|
|
82
|
+
- `decode()` 方法:bytes → object(使用 JSON)
|
|
83
|
+
- 所有 JSON 操作只在这一层
|
|
83
84
|
|
|
84
85
|
### 3. RPCManager/EventChannelManager(应用层)
|
|
85
86
|
- **职责**:业务逻辑处理
|
|
86
87
|
- **约束**:
|
|
87
|
-
- 内部永远使用类型化对象(RPCRequest/RPCResponse)
|
|
88
|
+
- 内部永远使用类型化对象(RPCRequest/RPCResponse/EventMessage)
|
|
88
89
|
- 调用 `encode()`/`decode()` 处理编解码
|
|
89
90
|
- 不直接使用 `json.dumps()`/`json.loads()`
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
支持自定义编解码器(例如 MessagePack):
|
|
94
|
-
|
|
95
|
-
```python
|
|
96
|
-
import msgpack
|
|
97
|
-
from mqttxx.protocol import Codec
|
|
98
|
-
|
|
99
|
-
class MessagePackCodec:
|
|
100
|
-
@staticmethod
|
|
101
|
-
def encode(obj) -> bytes:
|
|
102
|
-
if hasattr(obj, 'to_dict'):
|
|
103
|
-
data = obj.to_dict()
|
|
104
|
-
else:
|
|
105
|
-
data = obj
|
|
106
|
-
return msgpack.packb(data)
|
|
107
|
-
|
|
108
|
-
@staticmethod
|
|
109
|
-
def decode(data: bytes) -> dict:
|
|
110
|
-
return msgpack.unpackb(data, raw=False)
|
|
111
|
-
|
|
112
|
-
# 使用
|
|
113
|
-
from mqttxx import RPCManager
|
|
114
|
-
rpc = RPCManager(client, codec=MessagePackCodec)
|
|
115
|
-
```
|
|
92
|
+
**设计理念**:固定使用 JSON 编解码,简化架构,降低复杂度。如需自定义协议,可在传输层直接使用 `MQTTClient.subscribe()` 处理 bytes。
|
|
116
93
|
|
|
117
94
|
---
|
|
118
95
|
|
|
@@ -163,10 +140,10 @@ asyncio.run(main())
|
|
|
163
140
|
|
|
164
141
|
### 2. 约定式 RPC(零配置)
|
|
165
142
|
|
|
166
|
-
**推荐**:使用 `
|
|
143
|
+
**推荐**:使用 `RPCManager` 的 `my_topic` 参数,自动订阅 + 自动注入 reply_to。
|
|
167
144
|
|
|
168
145
|
```python
|
|
169
|
-
from mqttxx import MQTTClient, MQTTConfig,
|
|
146
|
+
from mqttxx import MQTTClient, MQTTConfig, RPCManager
|
|
170
147
|
|
|
171
148
|
# 边缘设备
|
|
172
149
|
async def edge_device():
|
|
@@ -178,7 +155,7 @@ async def edge_device():
|
|
|
178
155
|
|
|
179
156
|
async with MQTTClient(config) as client:
|
|
180
157
|
# 自动订阅 edge/device_123
|
|
181
|
-
rpc =
|
|
158
|
+
rpc = RPCManager(client, my_topic=f"edge/{client_id}")
|
|
182
159
|
|
|
183
160
|
@rpc.register("get_status")
|
|
184
161
|
async def get_status(params):
|
|
@@ -200,7 +177,7 @@ async def cloud_service():
|
|
|
200
177
|
|
|
201
178
|
async with MQTTClient(config) as client:
|
|
202
179
|
# 自动订阅 cloud/config-service
|
|
203
|
-
rpc =
|
|
180
|
+
rpc = RPCManager(client, my_topic=f"cloud/{client_id}")
|
|
204
181
|
|
|
205
182
|
@rpc.register("get_device_config")
|
|
206
183
|
async def get_device_config(params):
|
|
@@ -220,7 +197,7 @@ asyncio.run(edge_device()) # 或 asyncio.run(cloud_service())
|
|
|
220
197
|
|
|
221
198
|
| 场景 | 传统 RPC | 约定式 RPC |
|
|
222
199
|
|-----|---------|-----------|
|
|
223
|
-
| 初始化 | `rpc = RPCManager(client)`<br>`client.subscribe("edge/123", rpc.handle_rpc_message)` | `rpc =
|
|
200
|
+
| 初始化 | `rpc = RPCManager(client)`<br>`client.subscribe("edge/123", rpc.handle_rpc_message)` | `rpc = RPCManager(client, my_topic="edge/123")`<br>→ 自动订阅 |
|
|
224
201
|
| 调用 | `await rpc.call(topic="cloud/svc", method="get", reply_to="edge/123")` | `await rpc.call("cloud/svc", "get")` |
|
|
225
202
|
| 代码量 | 100% | **60%** ↓ |
|
|
226
203
|
|
|
@@ -293,7 +270,7 @@ asyncio.run(main())
|
|
|
293
270
|
|
|
294
271
|
```python
|
|
295
272
|
# 同时使用 RPC 和 Event Channel
|
|
296
|
-
rpc =
|
|
273
|
+
rpc = RPCManager(client, my_topic="device/device_001")
|
|
297
274
|
events = EventChannelManager(client)
|
|
298
275
|
|
|
299
276
|
# RPC: 获取配置(需要返回值)
|
|
@@ -400,6 +377,17 @@ async with MQTTClient(config) as client:
|
|
|
400
377
|
|
|
401
378
|
---
|
|
402
379
|
|
|
380
|
+
## 架构与实现
|
|
381
|
+
|
|
382
|
+
深入了解 MQTTX 的技术实现细节:
|
|
383
|
+
|
|
384
|
+
- **[消息路由实现逻辑](docs/routing_flow.md)** - 使用 Mermaid 图表说明从 MQTT Broker 到最终处理器的完整消息流程、订阅注册机制、通配符匹配算法,以及关键代码位置
|
|
385
|
+
- **[约定式 RPC 用法详解](docs/约定式RPC用法.md)** - 深入解析零配置 RPC 调用的设计原理、自动订阅机制、reply_to 自动注入,以及与传统 RPC 的对比
|
|
386
|
+
|
|
387
|
+
**推荐阅读顺序**:先通过上方的"快速开始"掌握基本用法,再深入技术文档了解底层实现。
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
403
391
|
## API 速查
|
|
404
392
|
|
|
405
393
|
### MQTTClient
|
|
@@ -422,7 +410,13 @@ class MQTTClient:
|
|
|
422
410
|
|
|
423
411
|
```python
|
|
424
412
|
class RPCManager:
|
|
425
|
-
def __init__(
|
|
413
|
+
def __init__(
|
|
414
|
+
self,
|
|
415
|
+
client: MQTTClient,
|
|
416
|
+
my_topic: Optional[str] = None,
|
|
417
|
+
config: RPCConfig = None,
|
|
418
|
+
auth_callback: AuthCallback = None
|
|
419
|
+
)
|
|
426
420
|
|
|
427
421
|
def register(self, method_name: str) # 装饰器
|
|
428
422
|
def unregister(self, method_name: str) -> None
|
|
@@ -440,14 +434,14 @@ class RPCManager:
|
|
|
440
434
|
|
|
441
435
|
---
|
|
442
436
|
|
|
443
|
-
###
|
|
437
|
+
### RPCManager(约定式用法)
|
|
444
438
|
|
|
445
439
|
```python
|
|
446
|
-
class
|
|
440
|
+
class RPCManager:
|
|
447
441
|
def __init__(
|
|
448
442
|
self,
|
|
449
443
|
client: MQTTClient,
|
|
450
|
-
my_topic: str, # 本节点 topic(自动订阅,自动注入到 reply_to)
|
|
444
|
+
my_topic: Optional[str] = None, # 本节点 topic(自动订阅,自动注入到 reply_to)
|
|
451
445
|
config: RPCConfig = None,
|
|
452
446
|
auth_callback: AuthCallback = None,
|
|
453
447
|
)
|
|
@@ -458,26 +452,26 @@ class ConventionalRPCManager(RPCManager):
|
|
|
458
452
|
method: str,
|
|
459
453
|
params: Any = None,
|
|
460
454
|
timeout: float = None,
|
|
461
|
-
reply_to: str = None, # 可选,默认使用 my_topic
|
|
455
|
+
reply_to: Optional[str] = None, # 可选,默认使用 my_topic
|
|
462
456
|
) -> Any
|
|
463
457
|
|
|
464
458
|
# 属性
|
|
465
|
-
my_topic: str # 当前 topic(只读)
|
|
459
|
+
my_topic: Optional[str] # 当前 topic(只读)
|
|
466
460
|
```
|
|
467
461
|
|
|
468
462
|
**使用示例:**
|
|
469
463
|
|
|
470
464
|
```python
|
|
471
465
|
# 边缘设备
|
|
472
|
-
rpc =
|
|
466
|
+
rpc = RPCManager(client, my_topic="edge/device_123")
|
|
473
467
|
config = await rpc.call("cloud/config-service", "get_config")
|
|
474
468
|
|
|
475
469
|
# 云端服务
|
|
476
|
-
rpc =
|
|
470
|
+
rpc = RPCManager(client, my_topic="cloud/config-service")
|
|
477
471
|
status = await rpc.call("edge/device_123", "execute_command")
|
|
478
472
|
|
|
479
473
|
# 微服务
|
|
480
|
-
rpc =
|
|
474
|
+
rpc = RPCManager(client, my_topic="auth-service")
|
|
481
475
|
user = await rpc.call("user-service", "get_user", params={"id": 123})
|
|
482
476
|
```
|
|
483
477
|
|
|
@@ -704,7 +698,34 @@ except RPCRemoteError as e:
|
|
|
704
698
|
|
|
705
699
|
---
|
|
706
700
|
|
|
707
|
-
##
|
|
701
|
+
## 版本变更
|
|
702
|
+
|
|
703
|
+
### v3.2.0(当前版本)
|
|
704
|
+
|
|
705
|
+
**架构简化**:
|
|
706
|
+
- ✅ **移除可插拔编解码器** - 固定使用 JSON 编解码,简化架构设计
|
|
707
|
+
- ✅ **整合约定式 RPC** - `my_topic` 参数集成到 `RPCManager`,移除独立的 `ConventionalRPCManager`
|
|
708
|
+
- ✅ **整合传输层 API** - `RawAPI` 功能整合到 `MQTTClient`,统一接口
|
|
709
|
+
|
|
710
|
+
**迁移指南(从 v3.1.x)**:
|
|
711
|
+
1. **移除 Codec 相关代码** - 不再支持自定义编解码器(如 MessagePack),统一使用 JSON
|
|
712
|
+
```python
|
|
713
|
+
# ❌ 旧代码(不再支持)
|
|
714
|
+
rpc = RPCManager(client, codec=MessagePackCodec)
|
|
715
|
+
|
|
716
|
+
# ✅ 新代码(固定 JSON)
|
|
717
|
+
rpc = RPCManager(client)
|
|
718
|
+
```
|
|
719
|
+
2. **使用约定式 RPC** - 推荐使用 `my_topic` 参数简化代码
|
|
720
|
+
```python
|
|
721
|
+
# ✅ 推荐写法
|
|
722
|
+
rpc = RPCManager(client, my_topic="edge/device_123")
|
|
723
|
+
result = await rpc.call("cloud/server", "get_config") # 自动注入 reply_to
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
---
|
|
727
|
+
|
|
728
|
+
### v2.0.0 重大变更
|
|
708
729
|
|
|
709
730
|
从 v2.0.0 开始,完全重写为基于 aiomqtt(纯 async/await),**不兼容** v0.x.x(gmqtt)。
|
|
710
731
|
|
|
@@ -712,13 +733,13 @@ except RPCRemoteError as e:
|
|
|
712
733
|
- ✅ aiomqtt 替代 gmqtt
|
|
713
734
|
- ✅ 原生 dataclass 替代 python-box(性能提升 6 倍)
|
|
714
735
|
- ✅ **修复所有 P0 缺陷**(详见下方)
|
|
715
|
-
- ✅ 新增约定式 RPC(`
|
|
736
|
+
- ✅ 新增约定式 RPC(`RPCManager` 的 `my_topic` 参数)
|
|
716
737
|
- ✅ 新增权限控制(`auth_callback`)
|
|
717
738
|
- ✅ 新增 TLS/SSL 支持
|
|
718
739
|
|
|
719
740
|
**P0 缺陷修复(v3.0)**:
|
|
720
741
|
1. **任务泄漏 + 消息处理模型** - Queue + Worker 模式,可控并发
|
|
721
|
-
2.
|
|
742
|
+
2. **取消订阅功能缺失** - 实现完整的取消订阅功能
|
|
722
743
|
3. **重连竞态条件** - 快照模式避免并发修改
|
|
723
744
|
4. **连接资源泄漏** - 显式关闭连接
|
|
724
745
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
mqttxx/__init__.py,sha256=_WoU5oZfMOJetRH1JkLuICp8PlqxpN3BWyXeZEjXeVo,1908
|
|
2
|
+
mqttxx/client.py,sha256=7umy-hJ-TUW9XD_rMdTh71q9Z7rlifnVPvHA80aIbcI,18794
|
|
3
|
+
mqttxx/config.py,sha256=A4AK54FL3eNyOCQ4E5IowIkC34zpT43d1bJzX0VOAHk,5986
|
|
4
|
+
mqttxx/events.py,sha256=bs7Khp6ygDK_aEOXftb74HO3SMqOY_Ln9Se_ro6ryiE,11747
|
|
5
|
+
mqttxx/exceptions.py,sha256=EC9NZmvZbfrK9iEdSyoYt4pUl0dp7yVup8mjOfgBaMw,3704
|
|
6
|
+
mqttxx/protocol.py,sha256=EwXJQ0Ic25oJx55coAfvntOxWh5FYYlBSMV93Cm6hHU,7445
|
|
7
|
+
mqttxx/rpc.py,sha256=KBu2006o9NukqbUk7ehvyIwgrdbO1CqY4rdo-OKr1KM,15831
|
|
8
|
+
mqttxx-3.2.1.dist-info/LICENSE,sha256=tfwCF8HPjAvvq_veljjH3_YL90X6ttkjTpRl3BGcXTg,1067
|
|
9
|
+
mqttxx-3.2.1.dist-info/METADATA,sha256=wFasvCdIOFRVZLnYEM84gxbRLE9uWd4CYa0VEtOFMGE,25544
|
|
10
|
+
mqttxx-3.2.1.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
11
|
+
mqttxx-3.2.1.dist-info/top_level.txt,sha256=4SNRXgOpGCT6ThBzAb8zhUmTyZwnIracAIJWAdXXzw0,7
|
|
12
|
+
mqttxx-3.2.1.dist-info/RECORD,,
|
mqttxx/conventions.py
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
# 约定式 RPC 管理器 - 去角色设计
|
|
2
|
-
|
|
3
|
-
from typing import Any, Optional, Type
|
|
4
|
-
from loguru import logger
|
|
5
|
-
|
|
6
|
-
from .client import MQTTClient
|
|
7
|
-
from .config import RPCConfig
|
|
8
|
-
from .rpc import RPCManager, AuthCallback
|
|
9
|
-
from .protocol import Codec, JSONCodec
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ConventionalRPCManager(RPCManager):
|
|
13
|
-
"""约定式 RPC 管理器
|
|
14
|
-
|
|
15
|
-
设计原则:
|
|
16
|
-
- 约定优于配置
|
|
17
|
-
- 自动订阅本地 topic
|
|
18
|
-
- 自动注入 reply_to
|
|
19
|
-
|
|
20
|
-
核心功能:
|
|
21
|
-
1. 初始化时自动订阅 `my_topic`
|
|
22
|
-
2. 调用时自动将 `my_topic` 注入到 `reply_to`
|
|
23
|
-
|
|
24
|
-
适用场景:
|
|
25
|
-
- 边缘设备 ↔ 云端(edge/xxx ↔ cloud/xxx)
|
|
26
|
-
- 微服务之间(auth-service ↔ user-service)
|
|
27
|
-
- IoT 网关 ↔ 设备(gateway/001 ↔ device/123)
|
|
28
|
-
- 任何需要简化 RPC 调用的场景
|
|
29
|
-
|
|
30
|
-
示例:
|
|
31
|
-
# 边缘设备
|
|
32
|
-
rpc = ConventionalRPCManager(client, my_topic="edge/device_123")
|
|
33
|
-
|
|
34
|
-
@rpc.register("get_status")
|
|
35
|
-
async def get_status(params):
|
|
36
|
-
return {"status": "online"}
|
|
37
|
-
|
|
38
|
-
# 调用云端(自动注入 reply_to="edge/device_123")
|
|
39
|
-
config = await rpc.call("cloud/config-service", "get_config")
|
|
40
|
-
|
|
41
|
-
# 云端服务
|
|
42
|
-
rpc = ConventionalRPCManager(client, my_topic="cloud/config-service")
|
|
43
|
-
|
|
44
|
-
# 调用边缘设备(自动注入 reply_to="cloud/config-service")
|
|
45
|
-
status = await rpc.call("edge/device_123", "execute_command")
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
def __init__(
|
|
49
|
-
self,
|
|
50
|
-
client: MQTTClient,
|
|
51
|
-
my_topic: str,
|
|
52
|
-
config: Optional[RPCConfig] = None,
|
|
53
|
-
auth_callback: Optional[AuthCallback] = None,
|
|
54
|
-
codec: Type[Codec] = JSONCodec, # 新增
|
|
55
|
-
):
|
|
56
|
-
"""初始化约定式 RPC 管理器
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
client: MQTTClient 实例
|
|
60
|
-
my_topic: 本节点的 topic(自动订阅,自动注入到 reply_to)
|
|
61
|
-
config: RPC 配置(可选)
|
|
62
|
-
auth_callback: 权限检查回调(可选)
|
|
63
|
-
codec: 编解码器(默认 JSONCodec)
|
|
64
|
-
|
|
65
|
-
自动行为:
|
|
66
|
-
- 自动订阅 my_topic(接收请求和响应)
|
|
67
|
-
- 自动绑定消息处理器
|
|
68
|
-
|
|
69
|
-
示例:
|
|
70
|
-
# 边缘设备
|
|
71
|
-
rpc = ConventionalRPCManager(client, my_topic="edge/device_123")
|
|
72
|
-
|
|
73
|
-
# 云端服务
|
|
74
|
-
rpc = ConventionalRPCManager(client, my_topic="cloud/server_001")
|
|
75
|
-
|
|
76
|
-
# 微服务
|
|
77
|
-
rpc = ConventionalRPCManager(client, my_topic="auth-service")
|
|
78
|
-
|
|
79
|
-
# 多层级
|
|
80
|
-
rpc = ConventionalRPCManager(client, my_topic="region/zone/device")
|
|
81
|
-
"""
|
|
82
|
-
super().__init__(client, config, auth_callback, codec)
|
|
83
|
-
|
|
84
|
-
self._my_topic = my_topic
|
|
85
|
-
|
|
86
|
-
# 自动设置(订阅响应主题)
|
|
87
|
-
self.setup(my_topic)
|
|
88
|
-
|
|
89
|
-
logger.info(f"ConventionalRPCManager 已初始化 - my_topic: {my_topic}")
|
|
90
|
-
|
|
91
|
-
async def call(
|
|
92
|
-
self,
|
|
93
|
-
topic: str,
|
|
94
|
-
method: str,
|
|
95
|
-
params: Any = None,
|
|
96
|
-
timeout: Optional[float] = None,
|
|
97
|
-
reply_to: Optional[str] = None,
|
|
98
|
-
) -> Any:
|
|
99
|
-
"""调用远程方法(自动注入 reply_to)
|
|
100
|
-
|
|
101
|
-
Args:
|
|
102
|
-
topic: 对方的 topic
|
|
103
|
-
method: 方法名
|
|
104
|
-
params: 参数(可选)
|
|
105
|
-
timeout: 超时时间(可选)
|
|
106
|
-
reply_to: 响应 topic(可选,默认使用 my_topic)
|
|
107
|
-
|
|
108
|
-
Returns:
|
|
109
|
-
方法返回值
|
|
110
|
-
|
|
111
|
-
Raises:
|
|
112
|
-
MQTTXError: 客户端未连接
|
|
113
|
-
RPCTimeoutError: 调用超时
|
|
114
|
-
RPCRemoteError: 远程执行失败
|
|
115
|
-
|
|
116
|
-
示例:
|
|
117
|
-
# 边缘设备调用云端
|
|
118
|
-
rpc = ConventionalRPCManager(client, my_topic="edge/device_123")
|
|
119
|
-
result = await rpc.call("cloud/server_001", "get_config")
|
|
120
|
-
# 等价于:await super().call("cloud/server_001", "get_config", reply_to="edge/device_123")
|
|
121
|
-
|
|
122
|
-
# 云端调用边缘设备
|
|
123
|
-
rpc = ConventionalRPCManager(client, my_topic="cloud/server_001")
|
|
124
|
-
result = await rpc.call("edge/device_123", "execute_command", params={"cmd": "restart"})
|
|
125
|
-
|
|
126
|
-
# 微服务调用
|
|
127
|
-
rpc = ConventionalRPCManager(client, my_topic="auth-service")
|
|
128
|
-
user = await rpc.call("user-service", "get_user", params={"id": 123})
|
|
129
|
-
"""
|
|
130
|
-
# 自动注入 reply_to
|
|
131
|
-
reply_to = reply_to or self._my_topic
|
|
132
|
-
|
|
133
|
-
return await super().call(
|
|
134
|
-
topic=topic,
|
|
135
|
-
method=method,
|
|
136
|
-
params=params,
|
|
137
|
-
timeout=timeout,
|
|
138
|
-
reply_to=reply_to,
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
@property
|
|
142
|
-
def my_topic(self) -> str:
|
|
143
|
-
"""获取当前节点的 topic
|
|
144
|
-
|
|
145
|
-
Returns:
|
|
146
|
-
当前节点订阅的 topic
|
|
147
|
-
"""
|
|
148
|
-
return self._my_topic
|
mqttxx-3.1.2.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
mqttxx/__init__.py,sha256=bNvLfcG5AgCpOrS1B4LEsDeVi-cKLuw0fYTOdlJoxS8,2072
|
|
2
|
-
mqttxx/client.py,sha256=lc1V6yPqq15PhmmU6L1Tspikg1b18jPLTkZe7ElmSTE,21807
|
|
3
|
-
mqttxx/config.py,sha256=A4AK54FL3eNyOCQ4E5IowIkC34zpT43d1bJzX0VOAHk,5986
|
|
4
|
-
mqttxx/conventions.py,sha256=ZP5FkYBCJiee1co041pbPv4x31i9HuG9KbeUFaDsoBs,4683
|
|
5
|
-
mqttxx/events.py,sha256=IG6ca4Gmm1P4sJUmZXTw6I2lHjVawJkpBjzX1GNerBM,11368
|
|
6
|
-
mqttxx/exceptions.py,sha256=EC9NZmvZbfrK9iEdSyoYt4pUl0dp7yVup8mjOfgBaMw,3704
|
|
7
|
-
mqttxx/protocol.py,sha256=GZYL2Fvi4-R0Tuyxrcp8-ttLWx9wyoH4-ZtzNq1wYxo,10034
|
|
8
|
-
mqttxx/rpc.py,sha256=6syEzmDZr2BQE2_LbdtrdTeWkrz3MAlAebbuX9O5-pY,15197
|
|
9
|
-
mqttxx-3.1.2.dist-info/LICENSE,sha256=tfwCF8HPjAvvq_veljjH3_YL90X6ttkjTpRl3BGcXTg,1067
|
|
10
|
-
mqttxx-3.1.2.dist-info/METADATA,sha256=ncDgBLxFEkCYeQhIz1nO3Mt5SUrodJq89U2ONATVoOg,24337
|
|
11
|
-
mqttxx-3.1.2.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
12
|
-
mqttxx-3.1.2.dist-info/top_level.txt,sha256=4SNRXgOpGCT6ThBzAb8zhUmTyZwnIracAIJWAdXXzw0,7
|
|
13
|
-
mqttxx-3.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|