signalrcore 0.9.5__py3-none-any.whl → 0.9.6a2__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.
Potentially problematic release.
This version of signalrcore might be problematic. Click here for more details.
- signalrcore/helpers.py +61 -0
- signalrcore/hub/base_hub_connection.py +70 -56
- signalrcore/hub/errors.py +2 -0
- signalrcore/hub/handlers.py +2 -2
- signalrcore/hub_connection_builder.py +27 -5
- signalrcore/protocol/base_hub_protocol.py +10 -6
- signalrcore/protocol/messagepack_protocol.py +26 -9
- signalrcore/transport/base_transport.py +11 -9
- signalrcore/transport/websockets/websocket_client.py +263 -0
- signalrcore/transport/websockets/websocket_transport.py +49 -58
- {signalrcore-0.9.5.dist-info → signalrcore-0.9.6a2.dist-info}/METADATA +16 -22
- {signalrcore-0.9.5.dist-info → signalrcore-0.9.6a2.dist-info}/RECORD +25 -23
- {signalrcore-0.9.5.dist-info → signalrcore-0.9.6a2.dist-info}/WHEEL +1 -1
- test/base_test_case.py +9 -4
- test/client_streaming_test.py +10 -14
- test/configuration_test.py +28 -26
- test/open_close_test.py +38 -29
- test/reconnection_test.py +46 -32
- test/send_auth_errors_test.py +18 -18
- test/send_auth_test.py +21 -18
- test/send_test.py +61 -36
- test/streaming_test.py +17 -18
- test/subscribe_test.py +18 -0
- {signalrcore-0.9.5.dist-info → signalrcore-0.9.6a2.dist-info}/LICENSE +0 -0
- {signalrcore-0.9.5.dist-info → signalrcore-0.9.6a2.dist-info}/top_level.txt +0 -0
signalrcore/helpers.py
CHANGED
|
@@ -1,8 +1,69 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import urllib.parse as parse
|
|
3
|
+
import urllib
|
|
4
|
+
import urllib.request
|
|
5
|
+
import ssl
|
|
6
|
+
from typing import Tuple
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RequestHelpers:
|
|
11
|
+
@staticmethod
|
|
12
|
+
def post(
|
|
13
|
+
url: str,
|
|
14
|
+
headers: dict = {},
|
|
15
|
+
proxies: dict = {},
|
|
16
|
+
verify_ssl: bool = False) -> Tuple[int, dict]:
|
|
17
|
+
return RequestHelpers.request(
|
|
18
|
+
url,
|
|
19
|
+
"POST",
|
|
20
|
+
headers=headers,
|
|
21
|
+
proxies=proxies,
|
|
22
|
+
verify_ssl=verify_ssl
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def request(
|
|
27
|
+
url: str,
|
|
28
|
+
method: str,
|
|
29
|
+
headers: dict = {},
|
|
30
|
+
proxies: dict = {},
|
|
31
|
+
verify_ssl: bool = False) -> Tuple[int, dict]:
|
|
32
|
+
context = ssl.create_default_context()
|
|
33
|
+
if not verify_ssl:
|
|
34
|
+
context.check_hostname = False
|
|
35
|
+
context.verify_mode = ssl.CERT_NONE
|
|
36
|
+
headers.update({'Content-Type': 'application/json'})
|
|
37
|
+
proxy_handler = None
|
|
38
|
+
|
|
39
|
+
if len(proxies.keys()) > 0:
|
|
40
|
+
proxy_handler = urllib.request.ProxyHandler(proxies)
|
|
41
|
+
|
|
42
|
+
req = urllib.request.Request(
|
|
43
|
+
url,
|
|
44
|
+
method=method,
|
|
45
|
+
headers=headers)
|
|
46
|
+
|
|
47
|
+
opener = urllib.request.build_opener(proxy_handler)\
|
|
48
|
+
if proxy_handler is not None else\
|
|
49
|
+
urllib.request.urlopen
|
|
50
|
+
|
|
51
|
+
with opener(
|
|
52
|
+
req,
|
|
53
|
+
context=context) as response:
|
|
54
|
+
status_code = response.getcode()
|
|
55
|
+
response_body = response.read().decode('utf-8')
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
json_data = json.loads(response_body)
|
|
59
|
+
except json.JSONDecodeError:
|
|
60
|
+
json_data = None
|
|
61
|
+
|
|
62
|
+
return status_code, json_data
|
|
3
63
|
|
|
4
64
|
|
|
5
65
|
class Helpers:
|
|
66
|
+
|
|
6
67
|
@staticmethod
|
|
7
68
|
def configure_logger(level=logging.INFO, handler=None):
|
|
8
69
|
logger = Helpers.get_logger()
|
|
@@ -1,30 +1,23 @@
|
|
|
1
|
-
from operator import inv
|
|
2
|
-
import websocket
|
|
3
|
-
import threading
|
|
4
|
-
import requests
|
|
5
|
-
import traceback
|
|
6
1
|
import uuid
|
|
7
|
-
import
|
|
8
|
-
import ssl
|
|
9
|
-
from typing import Callable
|
|
2
|
+
from typing import Callable, List, Union, Optional
|
|
10
3
|
from signalrcore.messages.message_type import MessageType
|
|
11
4
|
from signalrcore.messages.stream_invocation_message\
|
|
12
5
|
import StreamInvocationMessage
|
|
13
|
-
from
|
|
14
|
-
from .errors import UnAuthorizedHubError, HubError, HubConnectionError
|
|
6
|
+
from .errors import HubConnectionError
|
|
15
7
|
from signalrcore.helpers import Helpers
|
|
16
8
|
from .handlers import StreamHandler, InvocationHandler
|
|
17
|
-
from ..protocol.messagepack_protocol import MessagePackHubProtocol
|
|
18
9
|
from ..transport.websockets.websocket_transport import WebsocketTransport
|
|
19
|
-
from ..helpers import Helpers
|
|
20
10
|
from ..subject import Subject
|
|
21
11
|
from ..messages.invocation_message import InvocationMessage
|
|
12
|
+
from collections import defaultdict
|
|
13
|
+
|
|
22
14
|
|
|
23
15
|
class InvocationResult(object):
|
|
24
16
|
def __init__(self, invocation_id) -> None:
|
|
25
17
|
self.invocation_id = invocation_id
|
|
26
18
|
self.message = None
|
|
27
19
|
|
|
20
|
+
|
|
28
21
|
class BaseHubConnection(object):
|
|
29
22
|
def __init__(
|
|
30
23
|
self,
|
|
@@ -37,10 +30,12 @@ class BaseHubConnection(object):
|
|
|
37
30
|
else:
|
|
38
31
|
self.headers = headers
|
|
39
32
|
self.logger = Helpers.get_logger()
|
|
40
|
-
self.handlers =
|
|
41
|
-
self.stream_handlers =
|
|
33
|
+
self.handlers = defaultdict(list)
|
|
34
|
+
self.stream_handlers = defaultdict(list)
|
|
35
|
+
|
|
42
36
|
self._on_error = lambda error: self.logger.info(
|
|
43
37
|
"on_error not defined {0}".format(error))
|
|
38
|
+
|
|
44
39
|
self.transport = WebsocketTransport(
|
|
45
40
|
url=url,
|
|
46
41
|
protocol=protocol,
|
|
@@ -71,7 +66,7 @@ class BaseHubConnection(object):
|
|
|
71
66
|
connection.on_open(lambda: print(
|
|
72
67
|
"connection opened "))
|
|
73
68
|
Args:
|
|
74
|
-
callback (function):
|
|
69
|
+
callback (function): function without params
|
|
75
70
|
"""
|
|
76
71
|
self.transport.on_open_callback(callback)
|
|
77
72
|
|
|
@@ -101,30 +96,57 @@ class BaseHubConnection(object):
|
|
|
101
96
|
Args:
|
|
102
97
|
event (string): Event name
|
|
103
98
|
callback_function (Function): callback function,
|
|
104
|
-
arguments will be
|
|
99
|
+
arguments will be bound
|
|
105
100
|
"""
|
|
106
101
|
self.logger.debug("Handler registered started {0}".format(event))
|
|
107
|
-
self.handlers.append(
|
|
102
|
+
self.handlers[event].append(callback_function)
|
|
103
|
+
|
|
104
|
+
def unsubscribe(self, event, callback_function: Callable):
|
|
105
|
+
"""Removes a callback from the specified event
|
|
106
|
+
Args:
|
|
107
|
+
event (string): Event name
|
|
108
|
+
callback_function (Function): callback function,
|
|
109
|
+
arguments will be bound
|
|
110
|
+
"""
|
|
111
|
+
self.logger.debug("Handler removed {0}".format(event))
|
|
112
|
+
|
|
113
|
+
self.handlers[event].remove(callback_function)
|
|
114
|
+
|
|
115
|
+
if len(self.handlers[event]) == 0:
|
|
116
|
+
del self.handlers[event]
|
|
117
|
+
|
|
118
|
+
def send(self, method, arguments, on_invocation=None, invocation_id=None)\
|
|
119
|
+
-> InvocationResult:
|
|
120
|
+
return self.invoke(method, arguments, on_invocation, invocation_id)
|
|
108
121
|
|
|
109
|
-
def
|
|
110
|
-
|
|
122
|
+
def invoke(
|
|
123
|
+
self,
|
|
124
|
+
method: str,
|
|
125
|
+
arguments: Union[List, Subject],
|
|
126
|
+
on_invocation: Optional[Callable] = None,
|
|
127
|
+
invocation_id: Optional[str] = None)\
|
|
128
|
+
-> InvocationResult:
|
|
129
|
+
"""invokes a server function
|
|
111
130
|
|
|
112
131
|
Args:
|
|
113
132
|
method (string): Method name
|
|
114
133
|
arguments (list|Subject): Method parameters
|
|
115
134
|
on_invocation (function, optional): On invocation send callback
|
|
116
135
|
will be raised on send server function ends. Defaults to None.
|
|
117
|
-
invocation_id (string, optional): Override invocation ID.
|
|
118
|
-
thrown by the hub will use this ID,
|
|
119
|
-
with the on_error call.
|
|
136
|
+
invocation_id (string, optional): Override invocation ID.
|
|
137
|
+
Exceptions thrown by the hub will use this ID,
|
|
138
|
+
making it easier to handle with the on_error call.
|
|
120
139
|
|
|
121
140
|
Raises:
|
|
122
141
|
HubConnectionError: If hub is not ready to send
|
|
123
142
|
TypeError: If arguments are invalid list or Subject
|
|
124
143
|
"""
|
|
144
|
+
if invocation_id is None:
|
|
145
|
+
invocation_id = str(uuid.uuid4())
|
|
146
|
+
|
|
125
147
|
if not self.transport.is_running():
|
|
126
148
|
raise HubConnectionError(
|
|
127
|
-
"
|
|
149
|
+
"Cannot connect to SignalR hub. Unable to transmit messages")
|
|
128
150
|
|
|
129
151
|
if type(arguments) is not list and type(arguments) is not Subject:
|
|
130
152
|
raise TypeError("Arguments of a message must be a list or subject")
|
|
@@ -139,25 +161,23 @@ class BaseHubConnection(object):
|
|
|
139
161
|
headers=self.headers)
|
|
140
162
|
|
|
141
163
|
if on_invocation:
|
|
142
|
-
self.stream_handlers.append(
|
|
164
|
+
self.stream_handlers[message.invocation_id].append(
|
|
143
165
|
InvocationHandler(
|
|
144
166
|
message.invocation_id,
|
|
145
167
|
on_invocation))
|
|
146
|
-
|
|
168
|
+
|
|
147
169
|
self.transport.send(message)
|
|
148
170
|
result.message = message
|
|
149
|
-
|
|
171
|
+
|
|
150
172
|
if type(arguments) is Subject:
|
|
151
173
|
arguments.connection = self
|
|
152
174
|
arguments.target = method
|
|
153
175
|
arguments.start()
|
|
154
176
|
result.invocation_id = arguments.invocation_id
|
|
155
177
|
result.message = arguments
|
|
156
|
-
|
|
157
178
|
|
|
158
179
|
return result
|
|
159
180
|
|
|
160
|
-
|
|
161
181
|
def on_message(self, messages):
|
|
162
182
|
for message in messages:
|
|
163
183
|
if message.type == MessageType.invocation_binding_failure:
|
|
@@ -169,13 +189,14 @@ class BaseHubConnection(object):
|
|
|
169
189
|
continue
|
|
170
190
|
|
|
171
191
|
if message.type == MessageType.invocation:
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
self.handlers))
|
|
192
|
+
|
|
193
|
+
fired_handlers = self.handlers.get(message.target, [])
|
|
194
|
+
|
|
176
195
|
if len(fired_handlers) == 0:
|
|
177
|
-
self.logger.debug(
|
|
178
|
-
|
|
196
|
+
self.logger.debug(
|
|
197
|
+
f"event '{message.target}' hasn't fired any handler")
|
|
198
|
+
|
|
199
|
+
for handler in fired_handlers:
|
|
179
200
|
handler(message.arguments)
|
|
180
201
|
|
|
181
202
|
if message.type == MessageType.close:
|
|
@@ -188,30 +209,26 @@ class BaseHubConnection(object):
|
|
|
188
209
|
self._on_error(message)
|
|
189
210
|
|
|
190
211
|
# Send callbacks
|
|
191
|
-
fired_handlers =
|
|
192
|
-
|
|
193
|
-
lambda h: h.invocation_id == message.invocation_id,
|
|
194
|
-
self.stream_handlers))
|
|
212
|
+
fired_handlers = self.stream_handlers.get(
|
|
213
|
+
message.invocation_id, [])
|
|
195
214
|
|
|
196
215
|
# Stream callbacks
|
|
197
216
|
for handler in fired_handlers:
|
|
198
217
|
handler.complete_callback(message)
|
|
199
218
|
|
|
200
219
|
# unregister handler
|
|
201
|
-
self.stream_handlers
|
|
202
|
-
|
|
203
|
-
lambda h: h.invocation_id != message.invocation_id,
|
|
204
|
-
self.stream_handlers))
|
|
220
|
+
if message.invocation_id in self.stream_handlers:
|
|
221
|
+
del self.stream_handlers[message.invocation_id]
|
|
205
222
|
|
|
206
223
|
if message.type == MessageType.stream_item:
|
|
207
|
-
fired_handlers =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
self.stream_handlers))
|
|
224
|
+
fired_handlers = self.stream_handlers.get(
|
|
225
|
+
message.invocation_id, [])
|
|
226
|
+
|
|
211
227
|
if len(fired_handlers) == 0:
|
|
212
228
|
self.logger.warning(
|
|
213
229
|
"id '{0}' hasn't fire any stream handler".format(
|
|
214
230
|
message.invocation_id))
|
|
231
|
+
|
|
215
232
|
for handler in fired_handlers:
|
|
216
233
|
handler.next_callback(message.item)
|
|
217
234
|
|
|
@@ -219,10 +236,9 @@ class BaseHubConnection(object):
|
|
|
219
236
|
pass
|
|
220
237
|
|
|
221
238
|
if message.type == MessageType.cancel_invocation:
|
|
222
|
-
fired_handlers =
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
self.stream_handlers))
|
|
239
|
+
fired_handlers = self.stream_handlers.get(
|
|
240
|
+
message.invocation_id, [])
|
|
241
|
+
|
|
226
242
|
if len(fired_handlers) == 0:
|
|
227
243
|
self.logger.warning(
|
|
228
244
|
"id '{0}' hasn't fire any stream handler".format(
|
|
@@ -232,10 +248,8 @@ class BaseHubConnection(object):
|
|
|
232
248
|
handler.error_callback(message)
|
|
233
249
|
|
|
234
250
|
# unregister handler
|
|
235
|
-
self.stream_handlers
|
|
236
|
-
|
|
237
|
-
lambda h: h.invocation_id != message.invocation_id,
|
|
238
|
-
self.stream_handlers))
|
|
251
|
+
if message.invocation_id in self.stream_handlers:
|
|
252
|
+
del self.stream_handlers[message.invocation_id]
|
|
239
253
|
|
|
240
254
|
def stream(self, event, event_params):
|
|
241
255
|
"""Starts server streaming
|
|
@@ -256,11 +270,11 @@ class BaseHubConnection(object):
|
|
|
256
270
|
"""
|
|
257
271
|
invocation_id = str(uuid.uuid4())
|
|
258
272
|
stream_obj = StreamHandler(event, invocation_id)
|
|
259
|
-
self.stream_handlers.append(stream_obj)
|
|
273
|
+
self.stream_handlers[invocation_id].append(stream_obj)
|
|
260
274
|
self.transport.send(
|
|
261
275
|
StreamInvocationMessage(
|
|
262
276
|
invocation_id,
|
|
263
277
|
event,
|
|
264
278
|
event_params,
|
|
265
279
|
headers=self.headers))
|
|
266
|
-
return stream_obj
|
|
280
|
+
return stream_obj
|
signalrcore/hub/errors.py
CHANGED
signalrcore/hub/handlers.py
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import uuid
|
|
2
1
|
from .hub.base_hub_connection import BaseHubConnection
|
|
3
2
|
from .hub.auth_hub_connection import AuthHubConnection
|
|
4
3
|
from .transport.websockets.reconnection import \
|
|
5
4
|
IntervalReconnectionHandler, RawReconnectionHandler, ReconnectionType
|
|
6
5
|
from .helpers import Helpers
|
|
7
|
-
from .messages.invocation_message import InvocationMessage
|
|
8
6
|
from .protocol.json_hub_protocol import JsonHubProtocol
|
|
9
|
-
from .subject import Subject
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
class HubConnectionBuilder(object):
|
|
@@ -37,6 +34,7 @@ class HubConnectionBuilder(object):
|
|
|
37
34
|
self.enable_trace = False # socket trace
|
|
38
35
|
self.skip_negotiation = False # By default do not skip negotiation
|
|
39
36
|
self.running = False
|
|
37
|
+
self.proxies = dict()
|
|
40
38
|
|
|
41
39
|
def with_url(
|
|
42
40
|
self,
|
|
@@ -85,7 +83,7 @@ class HubConnectionBuilder(object):
|
|
|
85
83
|
if hub_url is None or hub_url.strip() == "":
|
|
86
84
|
raise ValueError("hub_url must be a valid url.")
|
|
87
85
|
|
|
88
|
-
if options is not None and type(options)
|
|
86
|
+
if options is not None and type(options) is not dict:
|
|
89
87
|
raise TypeError(
|
|
90
88
|
"options must be a dict {0}.".format(self.options))
|
|
91
89
|
|
|
@@ -127,6 +125,28 @@ class HubConnectionBuilder(object):
|
|
|
127
125
|
self.enable_trace = socket_trace
|
|
128
126
|
return self
|
|
129
127
|
|
|
128
|
+
def configure_proxies(
|
|
129
|
+
self,
|
|
130
|
+
proxies: dict):
|
|
131
|
+
"""configures proxies
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
proxies (dict): {
|
|
135
|
+
"http" : "http://host:port",
|
|
136
|
+
"https" : "https://host:port",
|
|
137
|
+
"ftp" : "ftp://port:port"
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
[HubConnectionBuilder]: Instance hub with proxies configured
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
if "http" not in proxies.keys() or "https" not in proxies.keys():
|
|
145
|
+
raise ValueError("Only http and https keys are allowed")
|
|
146
|
+
|
|
147
|
+
self.proxies = proxies
|
|
148
|
+
return self
|
|
149
|
+
|
|
130
150
|
def with_hub_protocol(self, protocol):
|
|
131
151
|
"""Changes transport protocol
|
|
132
152
|
from signalrcore.protocol.messagepack_protocol\
|
|
@@ -182,6 +202,7 @@ class HubConnectionBuilder(object):
|
|
|
182
202
|
keep_alive_interval=self.keep_alive_interval,
|
|
183
203
|
reconnection_handler=self.reconnection_handler,
|
|
184
204
|
verify_ssl=self.verify_ssl,
|
|
205
|
+
proxies=self.proxies,
|
|
185
206
|
skip_negotiation=self.skip_negotiation,
|
|
186
207
|
enable_trace=self.enable_trace)\
|
|
187
208
|
if self.has_auth_configured else\
|
|
@@ -192,9 +213,10 @@ class HubConnectionBuilder(object):
|
|
|
192
213
|
reconnection_handler=self.reconnection_handler,
|
|
193
214
|
headers=self.headers,
|
|
194
215
|
verify_ssl=self.verify_ssl,
|
|
216
|
+
proxies=self.proxies,
|
|
195
217
|
skip_negotiation=self.skip_negotiation,
|
|
196
218
|
enable_trace=self.enable_trace)
|
|
197
|
-
|
|
219
|
+
|
|
198
220
|
def with_automatic_reconnect(self, data: dict):
|
|
199
221
|
"""Configures automatic reconnection
|
|
200
222
|
https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-4/
|
|
@@ -10,7 +10,7 @@ from ..messages.cancel_invocation_message import CancelInvocationMessage # 5
|
|
|
10
10
|
from ..messages.ping_message import PingMessage # 6
|
|
11
11
|
from ..messages.close_message import CloseMessage # 7
|
|
12
12
|
from ..messages.message_type import MessageType
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
|
|
15
15
|
class BaseHubProtocol(object):
|
|
16
16
|
def __init__(self, protocol, version, transfer_format, record_separator):
|
|
@@ -21,9 +21,10 @@ class BaseHubProtocol(object):
|
|
|
21
21
|
|
|
22
22
|
@staticmethod
|
|
23
23
|
def get_message(dict_message):
|
|
24
|
-
message_type =
|
|
25
|
-
if
|
|
26
|
-
|
|
24
|
+
message_type = MessageType.close\
|
|
25
|
+
if "type" not in dict_message.keys() else\
|
|
26
|
+
MessageType(dict_message["type"])
|
|
27
|
+
|
|
27
28
|
dict_message["invocation_id"] = dict_message.get("invocationId", None)
|
|
28
29
|
dict_message["headers"] = dict_message.get("headers", {})
|
|
29
30
|
dict_message["error"] = dict_message.get("error", None)
|
|
@@ -45,10 +46,13 @@ class BaseHubProtocol(object):
|
|
|
45
46
|
|
|
46
47
|
def decode_handshake(self, raw_message: str) -> HandshakeResponseMessage:
|
|
47
48
|
messages = raw_message.split(self.record_separator)
|
|
48
|
-
messages = list(filter(lambda x: x != "", messages))
|
|
49
|
+
messages = list(filter(lambda x: x != "", messages))
|
|
49
50
|
data = json.loads(messages[0])
|
|
50
51
|
idx = raw_message.index(self.record_separator)
|
|
51
|
-
return
|
|
52
|
+
return (
|
|
53
|
+
HandshakeResponseMessage(data.get("error", None)),
|
|
54
|
+
self.parse_messages(raw_message[idx + 1:])
|
|
55
|
+
if len(messages) > 1 else [])
|
|
52
56
|
|
|
53
57
|
def handshake_message(self) -> HandshakeRequestMessage:
|
|
54
58
|
return HandshakeRequestMessage(self.protocol, self.version)
|
|
@@ -37,30 +37,47 @@ class MessagePackHubProtocol(BaseHubProtocol):
|
|
|
37
37
|
try:
|
|
38
38
|
messages = []
|
|
39
39
|
offset = 0
|
|
40
|
+
max_length_prefix_size = 5
|
|
41
|
+
num_bits_to_shift = [0, 7, 14, 21, 28]
|
|
40
42
|
while offset < len(raw):
|
|
41
|
-
length =
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
length = 0
|
|
44
|
+
num_bytes = 0
|
|
45
|
+
while True:
|
|
46
|
+
byte_read = raw[offset + num_bytes]
|
|
47
|
+
length |=\
|
|
48
|
+
(byte_read & 0x7F) << num_bits_to_shift[num_bytes]
|
|
49
|
+
num_bytes += 1
|
|
50
|
+
if byte_read & 0x80 == 0:
|
|
51
|
+
break
|
|
52
|
+
if offset == max_length_prefix_size\
|
|
53
|
+
or offset + num_bytes > len(raw):
|
|
54
|
+
raise Exception("Cannot read message length")
|
|
55
|
+
offset = offset + num_bytes
|
|
56
|
+
values = msgpack.unpackb(raw[offset: offset + length])
|
|
57
|
+
offset = offset + length
|
|
44
58
|
message = self._decode_message(values)
|
|
45
59
|
messages.append(message)
|
|
46
60
|
except Exception as ex:
|
|
47
|
-
|
|
48
|
-
|
|
61
|
+
self.logger.error("Parse messages Error {0}".format(ex))
|
|
62
|
+
self.logger.error("raw msg '{0}'".format(raw))
|
|
49
63
|
return messages
|
|
50
64
|
|
|
51
65
|
def decode_handshake(self, raw_message):
|
|
52
66
|
try:
|
|
53
67
|
has_various_messages = 0x1E in raw_message
|
|
54
|
-
handshake_data = raw_message[0: raw_message.index(0x1E)]
|
|
55
|
-
|
|
68
|
+
handshake_data = raw_message[0: raw_message.index(0x1E)]\
|
|
69
|
+
if has_various_messages else raw_message
|
|
70
|
+
messages = self.parse_messages(
|
|
71
|
+
raw_message[raw_message.index(0x1E) + 1:])\
|
|
72
|
+
if has_various_messages else []
|
|
56
73
|
data = json.loads(handshake_data)
|
|
57
74
|
return HandshakeResponseMessage(data.get("error", None)), messages
|
|
58
75
|
except Exception as ex:
|
|
59
76
|
if type(raw_message) is str:
|
|
60
77
|
data = json.loads(raw_message[0: raw_message.index("}") + 1])
|
|
61
78
|
return HandshakeResponseMessage(data.get("error", None)), []
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
self.logger.error(raw_message)
|
|
80
|
+
self.logger.error(ex)
|
|
64
81
|
raise ex
|
|
65
82
|
|
|
66
83
|
def encode(self, message):
|
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
from ..protocol.json_hub_protocol import JsonHubProtocol
|
|
2
2
|
from ..helpers import Helpers
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
class BaseTransport(object):
|
|
5
6
|
def __init__(self, protocol=JsonHubProtocol(), on_message=None):
|
|
6
7
|
self.protocol = protocol
|
|
7
|
-
self._on_message= on_message
|
|
8
|
+
self._on_message = on_message
|
|
8
9
|
self.logger = Helpers.get_logger()
|
|
9
10
|
self._on_open = lambda: self.logger.info("on_connect not defined")
|
|
10
11
|
self._on_close = lambda: self.logger.info("on_disconnect not defined")
|
|
11
|
-
self._on_reconnect
|
|
12
|
+
self._on_reconnect =\
|
|
13
|
+
lambda: self.logger.info("on_reconnect not defined")
|
|
12
14
|
|
|
13
15
|
def on_open_callback(self, callback):
|
|
14
16
|
self._on_open = callback
|
|
15
|
-
|
|
17
|
+
|
|
16
18
|
def on_close_callback(self, callback):
|
|
17
19
|
self._on_close = callback
|
|
18
20
|
|
|
19
21
|
def on_reconnect_callback(self, callback):
|
|
20
22
|
self._on_reconnect = callback
|
|
21
23
|
|
|
22
|
-
def start(self):
|
|
24
|
+
def start(self): # pragma: no cover
|
|
23
25
|
raise NotImplementedError()
|
|
24
26
|
|
|
25
|
-
def stop(self):
|
|
27
|
+
def stop(self): # pragma: no cover
|
|
26
28
|
raise NotImplementedError()
|
|
27
|
-
|
|
28
|
-
def is_running(self):
|
|
29
|
+
|
|
30
|
+
def is_running(self): # pragma: no cover
|
|
29
31
|
raise NotImplementedError()
|
|
30
32
|
|
|
31
|
-
def send(self, message, on_invocation
|
|
32
|
-
raise NotImplementedError()
|
|
33
|
+
def send(self, message, on_invocation=None): # pragma: no cover
|
|
34
|
+
raise NotImplementedError()
|