tendQuant 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tendQuant
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+ include setup.py
5
+ recursive-include tendquant *.py
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.1
2
+ Name: tendQuant
3
+ Version: 0.1.0
4
+ Summary: A MQTT client library for tendQuant
5
+ Home-page: https://github.com/top2189/tendQuant
6
+ Author: tendQuant
7
+ Author-email: tendQuant <fengyuan2189@gmail.com>
8
+ Project-URL: Homepage, https://github.com/top2189/tendQuant
9
+ Project-URL: Bug Tracker, https://github.com/top2189/tendQuant/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.7
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Requires-Python: >=3.7
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: paho-mqtt>=2.0.0
24
+
25
+ # tendQuant
26
+
27
+ A MQTT client library for tendQuant, supporting MQTTv5 and WebSocket.
28
+
29
+ ## Features
30
+
31
+ - **MQTTv5 Support**: Default use MQTTv5 protocol
32
+ - **WebSocket Support**: Support WebSocket connection
33
+ - **Auto Reconnect**: Automatic reconnection when disconnected
34
+ - **Easy API**: Simple subscribe/unsubscribe interface
35
+ - **Error Handling**: Detailed error messages and handling
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install tendQuant
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ### Basic Usage
46
+
47
+ ```python
48
+ from tendquant import MQTTClient
49
+
50
+ # Create client instance
51
+ client = MQTTClient(
52
+ broker="quant.top2189.cn",
53
+ port=80,
54
+ username="test",
55
+ password="test",
56
+ use_ws=True,
57
+ ws_path="/ws"
58
+ )
59
+
60
+ # Connect to broker
61
+ client.connect()
62
+
63
+ # Subscribe to topics
64
+ client.subscribe("lv1/tradeList/600089")
65
+ client.subscribe("lv1/tradeList/600111")
66
+
67
+ # Publish message
68
+ client.publish("test/topic", "Hello, MQTT!")
69
+
70
+ # Unsubscribe
71
+ client.unsubscribe("lv1/tradeList/600089")
72
+
73
+ # Disconnect
74
+ client.disconnect()
75
+ ```
76
+
77
+ ### Custom Message Handler
78
+
79
+ ```python
80
+ from tendquant import MQTTClient
81
+ import json
82
+
83
+ def custom_on_message(client, userdata, msg):
84
+ topic = msg.topic
85
+ payload = msg.payload.decode('utf-8')
86
+ data = json.loads(payload)
87
+ print(f"Received message on {topic}: {data}")
88
+
89
+ # Create client
90
+ client = MQTTClient("quant.top2189.cn", 80, use_ws=True, ws_path="/ws")
91
+
92
+ # Set custom message handler
93
+ client.client.on_message = custom_on_message
94
+
95
+ # Connect
96
+ client.connect()
97
+ ```
98
+
99
+ ## API Reference
100
+
101
+ ### MQTTClient
102
+
103
+ #### __init__(broker, port, username=None, password=None, keepalive=60, use_ws=False, ws_path="/mqtt")
104
+
105
+ Create a new MQTT client instance.
106
+
107
+ - `broker`: MQTT broker address
108
+ - `port`: MQTT broker port
109
+ - `username`: Username for authentication
110
+ - `password`: Password for authentication
111
+ - `keepalive`: Keepalive interval in seconds
112
+ - `use_ws`: Use WebSocket protocol
113
+ - `ws_path`: WebSocket path
114
+
115
+ #### connect()
116
+
117
+ Connect to MQTT broker.
118
+
119
+ #### subscribe(topic, qos=1)
120
+
121
+ Subscribe to a topic.
122
+
123
+ - `topic`: Topic to subscribe
124
+ - `qos`: Quality of Service level (0, 1, 2)
125
+
126
+ #### unsubscribe(topic)
127
+
128
+ Unsubscribe from a topic.
129
+
130
+ - `topic`: Topic to unsubscribe
131
+
132
+ #### publish(topic, payload, qos=0, retain=False)
133
+
134
+ Publish a message to a topic.
135
+
136
+ - `topic`: Topic to publish
137
+ - `payload`: Message payload
138
+ - `qos`: Quality of Service level
139
+ - `retain`: Retain message
140
+
141
+ #### disconnect()
142
+
143
+ Disconnect from MQTT broker.
144
+
145
+ ## License
146
+
147
+ MIT License
148
+
149
+ ## Contributing
150
+
151
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,127 @@
1
+ # tendQuant
2
+
3
+ A MQTT client library for tendQuant, supporting MQTTv5 and WebSocket.
4
+
5
+ ## Features
6
+
7
+ - **MQTTv5 Support**: Default use MQTTv5 protocol
8
+ - **WebSocket Support**: Support WebSocket connection
9
+ - **Auto Reconnect**: Automatic reconnection when disconnected
10
+ - **Easy API**: Simple subscribe/unsubscribe interface
11
+ - **Error Handling**: Detailed error messages and handling
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install tendQuant
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Basic Usage
22
+
23
+ ```python
24
+ from tendquant import MQTTClient
25
+
26
+ # Create client instance
27
+ client = MQTTClient(
28
+ broker="quant.top2189.cn",
29
+ port=80,
30
+ username="test",
31
+ password="test",
32
+ use_ws=True,
33
+ ws_path="/ws"
34
+ )
35
+
36
+ # Connect to broker
37
+ client.connect()
38
+
39
+ # Subscribe to topics
40
+ client.subscribe("lv1/tradeList/600089")
41
+ client.subscribe("lv1/tradeList/600111")
42
+
43
+ # Publish message
44
+ client.publish("test/topic", "Hello, MQTT!")
45
+
46
+ # Unsubscribe
47
+ client.unsubscribe("lv1/tradeList/600089")
48
+
49
+ # Disconnect
50
+ client.disconnect()
51
+ ```
52
+
53
+ ### Custom Message Handler
54
+
55
+ ```python
56
+ from tendquant import MQTTClient
57
+ import json
58
+
59
+ def custom_on_message(client, userdata, msg):
60
+ topic = msg.topic
61
+ payload = msg.payload.decode('utf-8')
62
+ data = json.loads(payload)
63
+ print(f"Received message on {topic}: {data}")
64
+
65
+ # Create client
66
+ client = MQTTClient("quant.top2189.cn", 80, use_ws=True, ws_path="/ws")
67
+
68
+ # Set custom message handler
69
+ client.client.on_message = custom_on_message
70
+
71
+ # Connect
72
+ client.connect()
73
+ ```
74
+
75
+ ## API Reference
76
+
77
+ ### MQTTClient
78
+
79
+ #### __init__(broker, port, username=None, password=None, keepalive=60, use_ws=False, ws_path="/mqtt")
80
+
81
+ Create a new MQTT client instance.
82
+
83
+ - `broker`: MQTT broker address
84
+ - `port`: MQTT broker port
85
+ - `username`: Username for authentication
86
+ - `password`: Password for authentication
87
+ - `keepalive`: Keepalive interval in seconds
88
+ - `use_ws`: Use WebSocket protocol
89
+ - `ws_path`: WebSocket path
90
+
91
+ #### connect()
92
+
93
+ Connect to MQTT broker.
94
+
95
+ #### subscribe(topic, qos=1)
96
+
97
+ Subscribe to a topic.
98
+
99
+ - `topic`: Topic to subscribe
100
+ - `qos`: Quality of Service level (0, 1, 2)
101
+
102
+ #### unsubscribe(topic)
103
+
104
+ Unsubscribe from a topic.
105
+
106
+ - `topic`: Topic to unsubscribe
107
+
108
+ #### publish(topic, payload, qos=0, retain=False)
109
+
110
+ Publish a message to a topic.
111
+
112
+ - `topic`: Topic to publish
113
+ - `payload`: Message payload
114
+ - `qos`: Quality of Service level
115
+ - `retain`: Retain message
116
+
117
+ #### disconnect()
118
+
119
+ Disconnect from MQTT broker.
120
+
121
+ ## License
122
+
123
+ MIT License
124
+
125
+ ## Contributing
126
+
127
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tendQuant"
7
+ version = "0.1.0"
8
+ authors = [
9
+ { name="tendQuant", email="fengyuan2189@gmail.com" }
10
+ ]
11
+ description = "A MQTT client library for tendQuant"
12
+ readme = "README.md"
13
+ requires-python = ">=3.7"
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.7",
21
+ "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ ]
26
+ dependencies = [
27
+ "paho-mqtt>=2.0.0",
28
+ ]
29
+
30
+ [project.scripts]
31
+ tendquant = "tendquant.cli:main"
32
+
33
+ [project.urls]
34
+ "Homepage" = "https://github.com/top2189/tendQuant"
35
+ "Bug Tracker" = "https://github.com/top2189/tendQuant/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r", encoding="utf-8") as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name="tendQuant",
8
+ version="0.1.0",
9
+ author="tendQuant",
10
+ author_email="fengyuan2189@gmail.com",
11
+ description="A MQTT client library for tendQuant",
12
+ long_description=long_description,
13
+ long_description_content_type="text/markdown",
14
+ url="https://github.com/top2189/tendQuant",
15
+ packages=find_packages(),
16
+ classifiers=[
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.7",
23
+ "Programming Language :: Python :: 3.8",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ ],
28
+ python_requires=">=3.7",
29
+ install_requires=[
30
+ "paho-mqtt>=2.0.0",
31
+ ],
32
+ entry_points={
33
+ "console_scripts": [
34
+ "tendquant = tendquant.cli:main",
35
+ ],
36
+ },
37
+ include_package_data=True,
38
+ )
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.1
2
+ Name: tendQuant
3
+ Version: 0.1.0
4
+ Summary: A MQTT client library for tendQuant
5
+ Home-page: https://github.com/top2189/tendQuant
6
+ Author: tendQuant
7
+ Author-email: tendQuant <fengyuan2189@gmail.com>
8
+ Project-URL: Homepage, https://github.com/top2189/tendQuant
9
+ Project-URL: Bug Tracker, https://github.com/top2189/tendQuant/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.7
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Requires-Python: >=3.7
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: paho-mqtt>=2.0.0
24
+
25
+ # tendQuant
26
+
27
+ A MQTT client library for tendQuant, supporting MQTTv5 and WebSocket.
28
+
29
+ ## Features
30
+
31
+ - **MQTTv5 Support**: Default use MQTTv5 protocol
32
+ - **WebSocket Support**: Support WebSocket connection
33
+ - **Auto Reconnect**: Automatic reconnection when disconnected
34
+ - **Easy API**: Simple subscribe/unsubscribe interface
35
+ - **Error Handling**: Detailed error messages and handling
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install tendQuant
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ### Basic Usage
46
+
47
+ ```python
48
+ from tendquant import MQTTClient
49
+
50
+ # Create client instance
51
+ client = MQTTClient(
52
+ broker="quant.top2189.cn",
53
+ port=80,
54
+ username="test",
55
+ password="test",
56
+ use_ws=True,
57
+ ws_path="/ws"
58
+ )
59
+
60
+ # Connect to broker
61
+ client.connect()
62
+
63
+ # Subscribe to topics
64
+ client.subscribe("lv1/tradeList/600089")
65
+ client.subscribe("lv1/tradeList/600111")
66
+
67
+ # Publish message
68
+ client.publish("test/topic", "Hello, MQTT!")
69
+
70
+ # Unsubscribe
71
+ client.unsubscribe("lv1/tradeList/600089")
72
+
73
+ # Disconnect
74
+ client.disconnect()
75
+ ```
76
+
77
+ ### Custom Message Handler
78
+
79
+ ```python
80
+ from tendquant import MQTTClient
81
+ import json
82
+
83
+ def custom_on_message(client, userdata, msg):
84
+ topic = msg.topic
85
+ payload = msg.payload.decode('utf-8')
86
+ data = json.loads(payload)
87
+ print(f"Received message on {topic}: {data}")
88
+
89
+ # Create client
90
+ client = MQTTClient("quant.top2189.cn", 80, use_ws=True, ws_path="/ws")
91
+
92
+ # Set custom message handler
93
+ client.client.on_message = custom_on_message
94
+
95
+ # Connect
96
+ client.connect()
97
+ ```
98
+
99
+ ## API Reference
100
+
101
+ ### MQTTClient
102
+
103
+ #### __init__(broker, port, username=None, password=None, keepalive=60, use_ws=False, ws_path="/mqtt")
104
+
105
+ Create a new MQTT client instance.
106
+
107
+ - `broker`: MQTT broker address
108
+ - `port`: MQTT broker port
109
+ - `username`: Username for authentication
110
+ - `password`: Password for authentication
111
+ - `keepalive`: Keepalive interval in seconds
112
+ - `use_ws`: Use WebSocket protocol
113
+ - `ws_path`: WebSocket path
114
+
115
+ #### connect()
116
+
117
+ Connect to MQTT broker.
118
+
119
+ #### subscribe(topic, qos=1)
120
+
121
+ Subscribe to a topic.
122
+
123
+ - `topic`: Topic to subscribe
124
+ - `qos`: Quality of Service level (0, 1, 2)
125
+
126
+ #### unsubscribe(topic)
127
+
128
+ Unsubscribe from a topic.
129
+
130
+ - `topic`: Topic to unsubscribe
131
+
132
+ #### publish(topic, payload, qos=0, retain=False)
133
+
134
+ Publish a message to a topic.
135
+
136
+ - `topic`: Topic to publish
137
+ - `payload`: Message payload
138
+ - `qos`: Quality of Service level
139
+ - `retain`: Retain message
140
+
141
+ #### disconnect()
142
+
143
+ Disconnect from MQTT broker.
144
+
145
+ ## License
146
+
147
+ MIT License
148
+
149
+ ## Contributing
150
+
151
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,14 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ setup.py
6
+ tendQuant.egg-info/PKG-INFO
7
+ tendQuant.egg-info/SOURCES.txt
8
+ tendQuant.egg-info/dependency_links.txt
9
+ tendQuant.egg-info/entry_points.txt
10
+ tendQuant.egg-info/requires.txt
11
+ tendQuant.egg-info/top_level.txt
12
+ tendquant/__init__.py
13
+ tendquant/cli.py
14
+ tendquant/mqtt_client.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tendquant = tendquant.cli:main
@@ -0,0 +1 @@
1
+ paho-mqtt>=2.0.0
@@ -0,0 +1 @@
1
+ tendquant
@@ -0,0 +1,7 @@
1
+ from .mqtt_client import MQTTClient
2
+
3
+ __version__ = "0.1.0"
4
+ __author__ = "tendQuant"
5
+ __email__ = "fengyuan2189@gmail.com"
6
+
7
+ __all__ = ["MQTTClient"]
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ tendQuant CLI tool
4
+ """
5
+ import argparse
6
+ from .mqtt_client import MQTTClient
7
+
8
+ def main():
9
+ parser = argparse.ArgumentParser(description="tendQuant MQTT Client CLI")
10
+ parser.add_argument("--broker", help="MQTT broker address")
11
+ parser.add_argument("--port", type=int, help="MQTT broker port")
12
+ parser.add_argument("--username", help="MQTT username")
13
+ parser.add_argument("--password", help="MQTT password")
14
+ parser.add_argument("--use-ws", action="store_true", help="Use WebSocket protocol")
15
+ parser.add_argument("--ws-path", default="/mqtt", help="WebSocket path")
16
+ parser.add_argument("--subscribe", help="Topic to subscribe")
17
+ parser.add_argument("--publish", help="Message to publish")
18
+ parser.add_argument("--topic", help="Topic for publishing")
19
+
20
+ args = parser.parse_args()
21
+
22
+ # Create client
23
+ client = MQTTClient(
24
+ broker=args.broker,
25
+ port=args.port,
26
+ username=args.username,
27
+ password=args.password,
28
+ use_ws=args.use_ws,
29
+ ws_path=args.ws_path
30
+ )
31
+
32
+ # Connect
33
+ client.connect()
34
+
35
+ # Subscribe
36
+ if args.subscribe:
37
+ client.subscribe(args.subscribe)
38
+ print(f"Subscribed to {args.subscribe}")
39
+
40
+ # Publish
41
+ if args.publish and args.topic:
42
+ client.publish(args.topic, args.publish)
43
+ print(f"Published to {args.topic}: {args.publish}")
44
+
45
+ # Keep running
46
+ try:
47
+ while True:
48
+ pass
49
+ except KeyboardInterrupt:
50
+ client.disconnect()
51
+ print("\nDisconnected")
52
+
53
+ if __name__ == "__main__":
54
+ main()
@@ -0,0 +1,181 @@
1
+ import paho.mqtt.client as mqtt
2
+ import random
3
+ import string
4
+ import time
5
+
6
+ class MQTTClient:
7
+ def __init__(self, broker, port, username=None, password=None, keepalive=60, use_ws=True, ws_path="/mqtt"):
8
+ self.broker = broker
9
+ self.port = port
10
+ self.username = username
11
+ self.password = password
12
+ self.keepalive = keepalive
13
+ self.use_ws = use_ws
14
+ self.ws_path = ws_path
15
+ self.client = None
16
+ self.connected = False
17
+
18
+ # 生成随机CLIENT_ID
19
+ self.client_id = self._generate_client_id()
20
+
21
+ # 初始化客户端
22
+ self._init_client()
23
+
24
+ def _generate_client_id(self):
25
+ # 生成随机字符串作为CLIENT_ID
26
+ return 'mqtt-client-' + ''.join(random.choices(string.ascii_letters + string.digits, k=10))
27
+
28
+ def _init_client(self):
29
+ # 使用MqttV5版本和VERSION2回调API
30
+ self.client = mqtt.Client(
31
+ callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
32
+ transport="websockets" if self.use_ws else "tcp",
33
+ client_id=self.client_id,
34
+ protocol=mqtt.MQTTv5
35
+ )
36
+
37
+ # 设置用户名和密码
38
+ if self.username and self.password:
39
+ self.client.username_pw_set(self.username, self.password)
40
+
41
+ # 如果使用WebSocket协议
42
+ if self.use_ws:
43
+ self.client.ws_set_options(path=self.ws_path)
44
+
45
+ # 设置回调函数
46
+ self.client.on_connect = self._on_connect
47
+ self.client.on_disconnect = self._on_disconnect
48
+ self.client.on_message = self._on_message
49
+
50
+ def _on_connect(self, client, userdata, flags, rc, properties=None):
51
+ if rc == 0:
52
+ print(f">>> 成功连接到行情服务器")
53
+ self.connected = True
54
+
55
+ # 计算连接延迟
56
+ if hasattr(self, 'connect_start_time'):
57
+ connect_delay = time.time() - self.connect_start_time
58
+ print(f">>> 连接延迟: {connect_delay:.2f} 秒")
59
+
60
+ # 重新订阅之前的主题
61
+ if hasattr(self, 'subscribed_topics'):
62
+ for topic, qos in self.subscribed_topics:
63
+ client.subscribe(topic, qos)
64
+ print(f">>> 已订阅主题: {topic}")
65
+ else:
66
+ print(f"!!! 连接失败,错误码: {rc}")
67
+
68
+ def _on_disconnect(self, client, *args, **kwargs):
69
+ """断开连接回调"""
70
+ # args 通常包含 (userdata, rc, properties)
71
+ # 我们尝试获取 rc,它是第二个参数 (索引为1)
72
+ rc = 0
73
+ if len(args) >= 2:
74
+ rc = args[1]
75
+
76
+ if rc != 0:
77
+ print(f"### 意外断开连接,错误码: {rc}")
78
+ else:
79
+ print("### 连接已正常关闭")
80
+
81
+ self.connected = False
82
+ # 尝试重连
83
+ self._reconnect()
84
+
85
+ def _on_message(self, client, userdata, msg):
86
+ # 默认消息处理,可以在子类中重写
87
+ print(f"Received message on topic {msg.topic}: {msg.payload.decode()}")
88
+
89
+ def _reconnect(self):
90
+ while not self.connected:
91
+ try:
92
+ print(f"### 已断线,尝试重连中")
93
+ self.client.reconnect()
94
+ self.connected = True
95
+ except Exception as e:
96
+ print(f"Reconnection failed: {e}")
97
+ time.sleep(5)
98
+
99
+ def connect(self, on_message=None):
100
+ try:
101
+ # 设置消息回调
102
+ if on_message:
103
+ self.client.on_message = on_message
104
+
105
+ # 配置 MQTT 5 连接属性
106
+ connect_props = mqtt.Properties(mqtt.PacketTypes.CONNECT)
107
+ connect_props.SessionExpiryInterval = 0
108
+
109
+ # 记录连接开始时间
110
+ self.connect_start_time = time.time()
111
+
112
+ # print(f"正在连接到 {self.broker}:{self.port} (Path: {self.ws_path if self.use_ws else 'TCP'}) ...")
113
+ self.client.connect(self.broker, self.port, self.keepalive, properties=connect_props)
114
+ self.client.loop_start()
115
+
116
+ time.sleep(2)
117
+
118
+ return None
119
+ except Exception as e:
120
+ print(f"发生错误: {e}")
121
+ self._reconnect()
122
+ return None
123
+
124
+ def subscribe(self, topic, qos=1):
125
+ if self.connected:
126
+ try:
127
+ result, mid = self.client.subscribe(topic, qos)
128
+ if result == mqtt.MQTT_ERR_SUCCESS:
129
+ # 保存订阅的主题以便重连后重新订阅
130
+ if not hasattr(self, 'subscribed_topics'):
131
+ self.subscribed_topics = set()
132
+ self.subscribed_topics.add((topic, qos))
133
+ print(f">>> 已订阅主题: {topic}")
134
+ else:
135
+ error_messages = {
136
+ mqtt.MQTT_ERR_NO_CONN: "未连接到MQTT broker",
137
+ mqtt.MQTT_ERR_QUEUE_SIZE: "队列已满",
138
+ mqtt.MQTT_ERR_INVAL: "无效参数",
139
+ mqtt.MQTT_ERR_NOMEM: "内存不足",
140
+ mqtt.MQTT_ERR_PROTOCOL: "协议错误",
141
+ mqtt.MQTT_ERR_NOT_SUPPORTED: "不支持的操作",
142
+ mqtt.MQTT_ERR_TLS: "TLS错误",
143
+ mqtt.MQTT_ERR_PAYLOAD_SIZE: "负载大小超出限制",
144
+ mqtt.MQTT_ERR_NOT_AUTHORIZED: "未授权访问",
145
+ mqtt.MQTT_ERR_UNKNOWN: "未知错误"
146
+ }
147
+ error_msg = error_messages.get(result, f"错误码: {result}")
148
+ print(f"!!! 订阅失败: {error_msg}")
149
+ except Exception as e:
150
+ print(f"!!! 订阅时出错: {e}")
151
+ else:
152
+ print("!!! 未连接到MQTT broker")
153
+
154
+ def unsubscribe(self, topic):
155
+ if self.connected:
156
+ try:
157
+ result, mid = self.client.unsubscribe(topic)
158
+ if result == mqtt.MQTT_ERR_SUCCESS:
159
+ # 从保存的主题中移除
160
+ if hasattr(self, 'subscribed_topics'):
161
+ # 移除所有匹配该主题的订阅
162
+ self.subscribed_topics = {(t, q) for t, q in self.subscribed_topics if t != topic}
163
+ print(f">>> 已取消订阅主题: {topic}")
164
+ else:
165
+ print(f"!!! 取消订阅失败,错误码: {result}")
166
+ except Exception as e:
167
+ print(f"!!! 取消订阅时出错: {e}")
168
+ else:
169
+ print("!!! 未连接到MQTT broker")
170
+
171
+ def publish(self, topic, payload, qos=0, retain=False):
172
+ if self.connected:
173
+ self.client.publish(topic, payload, qos, retain)
174
+ else:
175
+ print("!!! 未连接到MQTT broker")
176
+
177
+ def disconnect(self):
178
+ self.client.loop_stop()
179
+ self.client.disconnect()
180
+ self.connected = False
181
+ print("### 已断开与行情服务器的连接")