Ananto30 / zero

Zero: A simple and fast Python RPC framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

question

nadongjin opened this issue · comments

I am sending serialized data to the server. However, for example, when I open Chrome, enter the server IP in the URL, and press Enter, I always encounter the following type error in the server console. This doesn't affect the service, but is there a way to resolve this?

#############################################################################################
23-Aug-23 17:19:06 ERROR 20283 worker > MessagePack data is malformed: trailing characters (byte 1)
Traceback (most recent call last):
File "/home/facetag/Project1/venv/lib/python3.10/site-packages/zero/client_server/worker.py", line 39, in process_message
decoded = self._encoder.decode(data)
File "/home/facetag/Project1/venv/lib/python3.10/site-packages/zero/encoder/msgspc.py", line 16, in decode
return decoder.decode(data)
msgspec.DecodeError: MessagePack data is malformed: trailing characters (byte 1)
23-Aug-23 17:19:06 ERROR 20283 worker > Frame 1 (None) does not support the buffer interface.
Traceback (most recent call last):
File "/home/facetag/Project1/venv/lib/python3.10/site-packages/zmq/sugar/socket.py", line 738, in send_multipart
memoryview(msg)
TypeError: memoryview: a bytes-like object is required, not 'NoneType'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/facetag/Project1/venv/lib/python3.10/site-packages/zero/client_server/worker.py", line 50, in start_dealer_worker
worker.listen(self._device_comm_channel, process_message)
File "/home/facetag/Project1/venv/lib/python3.10/site-packages/zero/zero_mq/queue_device/worker.py", line 37, in listen
self.socket.send_multipart([ident, response], zmq.NOBLOCK)
File "/home/facetag/Project1/venv/lib/python3.10/site-packages/zmq/sugar/socket.py", line 743, in send_multipart
raise TypeError(
TypeError: Frame 1 (None) does not support the buffer interface.

Hi @nadongjin Zero is not a HTTP server, so if you just put the URL in browser and it won't work :D The protocol underlying is TCP but wrapped with zeromq packets. So you can do the talking using codes and for now only Zero can talk with Zero, no other language or framework can interact with Zero, because the way it arrange its packets in the network. So, to talk to a ZeroServer, you need a ZeroClient.

#Thank you for your swift response. I am well aware of the points you mentioned earlier. I am utilizing the Zero Server to receive bytes and then transmit them to the Zero Client as bytes. However, upon attempting to access the Zero Server's IP and port via http://ip:port/, I consistently encounter the error message "TypeError: memoryview: a bytes-like object is required, not 'NoneType'" in the Zero Server's console. [Significant Vulnerability] Eventually, the Zero Server has ceased its service operation. I am curious if there exists a way to validate the protocol as HTTP or implement validation for the data sent from the client.
[Many external users perform port scanning tests, so if a Zeroserver worker goes down, it becomes a problem.]

===>I have temporarily resolved this issue.
By providing dummy values, I prevented the worker from crashing when an error occurred, and I hid the error messages. This was a temporary solution I applied due to issues with my service. : )
##################################################################
[worker.py]
def start_dealer_worker(self, worker_id):
def process_message(data: bytes) -> Optional[bytes]:
try:
decoded = self._encoder.decode(data)
req_id, func_name, msg = decoded
response = self.handle_msg(func_name, msg)
return self._encoder.encode([req_id, response])
except Exception as inner_exc: # pylint: disable=broad-except
# logging.exception(inner_exc) <----Commenting out to suppress error logs in the console.
return self._encoder.encode(['dummy']) <-----I provided dummy values to prevent the worker from crashing.
# TODO what to return
# return None

[msgspc.py]
class MsgspecEncoder:
def init(self):
pass
def encode(self, data):
return encoder.encode(data)
def decode(self, data):
try:
decode_data=decoder.decode(data)
return decode_data
except:
pass <-----I skipped it when an error occurred.

Ah interesting! Sorry I didn't get your point earlier.

Seems like a big finding! Thanks! I will check today. From a high level view from your sharing, it is returning None when failing to handle message, and that is fed on the zmq send_multipart.

My concept was a RPC function should never return None. But I violated my own theory here 😅 I will make a fix soon, thanks again!

Hmm, it's actually not about the return in the handle_message function, so returning None is fine. It's more about what if there is a http request in land in this server, it was crashing before, and now made a PR to fix that. Thanks @nadongjin 🙌