-
-
Notifications
You must be signed in to change notification settings - Fork 148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix the bytearray has not .encode() error #31
Conversation
@wwqgtxx what payload did you send from the client that ended up being a bytearray on the server side? |
if the websocket opcode is 0x2 |
As we know,the socket.io protocol alow the binary data send by two way.One is send a base64encode data which start with |
Sorry, but it seems you are confusing websocket with Socket.IO. My question was which Socket.IO client sends packets that on the server appear as byte arrays. All the tests I've done with the official Socket.IO clients send bytes, not byte arrays. If you are using a plain websocket client and expecting Socket.IO on the server will understand that then that's the problem, these two protocols are not compatible, you need to use a Socket.IO client. |
I am trying to make python's socketIO-client support binary data send,and add this pr to socketIO-client the data send and receive like this (log by client):
|
Ah, okay, that makes sense. So this is the python Socket.IO client. On the server, are you using eventlet, gevent or uwsgi? |
I use gevent. |
I found this problem cause by def read_message(self):
"""
Return the next text or binary message from the socket.
This is an internal method as calling this will not cleanup correctly
if an exception is called. Use `receive` instead.
"""
opcode = None
message = bytearray()
while True:
header, payload = self.read_frame()
f_opcode = header.opcode
if f_opcode in (self.OPCODE_TEXT, self.OPCODE_BINARY):
# a new frame
if opcode:
raise ProtocolError("The opcode in non-fin frame is "
"expected to be zero, got "
"{0!r}".format(f_opcode))
# Start reading a new message, reset the validator
self.utf8validator.reset()
self.utf8validate_last = (True, True, 0, 0)
opcode = f_opcode
elif f_opcode == self.OPCODE_CONTINUATION:
if not opcode:
raise ProtocolError("Unexpected frame with opcode=0")
elif f_opcode == self.OPCODE_PING:
self.handle_ping(header, payload)
continue
elif f_opcode == self.OPCODE_PONG:
self.handle_pong(header, payload)
continue
elif f_opcode == self.OPCODE_CLOSE:
self.handle_close(header, payload)
return
else:
raise ProtocolError("Unexpected opcode={0!r}".format(f_opcode))
if opcode == self.OPCODE_TEXT:
self.validate_utf8(payload)
message += payload
if header.fin:
break
if opcode == self.OPCODE_TEXT:
self.validate_utf8(message)
return str(message, "utf-8")
else:
return message because it recevie a |
Above def read_message(self):
"""
Return the next text or binary message from the socket.
This is an internal method as calling this will not cleanup correctly
if an exception is called. Use `receive` instead.
"""
opcode = None
message = ""
while True:
header, payload = self.read_frame()
f_opcode = header.opcode
if f_opcode in (self.OPCODE_TEXT, self.OPCODE_BINARY):
# a new frame
if opcode:
raise ProtocolError("The opcode in non-fin frame is "
"expected to be zero, got "
"{0!r}".format(f_opcode))
# Start reading a new message, reset the validator
self.utf8validator.reset()
self.utf8validate_last = (True, True, 0, 0)
opcode = f_opcode
elif f_opcode == self.OPCODE_CONTINUATION:
if not opcode:
raise ProtocolError("Unexpected frame with opcode=0")
elif f_opcode == self.OPCODE_PING:
self.handle_ping(header, payload)
continue
elif f_opcode == self.OPCODE_PONG:
self.handle_pong(header, payload)
continue
elif f_opcode == self.OPCODE_CLOSE:
self.handle_close(header, payload)
return
else:
raise ProtocolError("Unexpected opcode={0!r}".format(f_opcode))
if opcode == self.OPCODE_TEXT:
self.validate_utf8(payload)
message += payload
if header.fin:
break
if opcode == self.OPCODE_TEXT:
self.validate_utf8(message)
return message
else:
return bytearray(message) |
Okay, that explains it. Thanks for the detailed analysis. I did not find this problem myself because I rarely use gevent-websocket for my testing, since it has never been ported to Python 3. I should give the 3.5 fork a try, I guess. |
@wwqgtxx Thanks, the PR is now merged. I have added a couple other places where binary types were being checked, plus some unit tests. |
Only a suggest that you can try to use ws4py package to support the gevent on both python2 and python3. |
Thanks, I will take a look at ws4py and see if I can integrate it. |
No description provided.