diff --git a/socketIO_client/__init__.py b/socketIO_client/__init__.py index 4552103..05492d9 100644 --- a/socketIO_client/__init__.py +++ b/socketIO_client/__init__.py @@ -444,7 +444,7 @@ class SocketIO(object): _log.debug("[event] %s (%s)" % (repr(event), repr(args))); if packet.payload.id is not None: - args.append(self._prepare_to_send_ack(path, packet_id)) + args.append(self._prepare_to_send_ack(packet.payload.path, packet.payload.id)) find_event_callback(event)(*args); def _on_ack(self, packet, find_event_callback): diff --git a/socketIO_client/parser.py b/socketIO_client/parser.py index 3e657d0..8fe06b1 100644 --- a/socketIO_client/parser.py +++ b/socketIO_client/parser.py @@ -32,6 +32,27 @@ class Packet(): def __str__(self): return "PACKET{type: " + str(self.type) + ", payload: " + str(self.payload) + "}"; + def encode_as_string(self, for_websocket = False): + data = ""; + path = ""; + if self.type == PacketType.MESSAGE: + data = self.payload.encode_as_string(); + path = self.payload.path; + else: + data = self.payload; + + code_length = len(str(self.type)); + data_length = len(data); + length = code_length + data_length; + + encoded = ""; + if for_websocket: + encoded = str(self.type) + str(data); + else: + encoded = str(length) + ":" + str(self.type) + str(data); + + return encoded; + class Message(): def __init__(self, message_type, message, path = "", attachments = "", message_id = None): self.type = message_type; @@ -67,15 +88,30 @@ class Message(): Assumes the message payload will be dumped as a json string. """ + data = json.dumps(self.message); + if self.id is not None: + data = str(self.id) + json.dumps(self.message); + if self.path == "": - return str(self.type) + json.dumps(self.message); - return str(self.type) + self.path + "," + json.dumps(self.message); + return str(self.type) + data; + return str(self.type) + self.path + "," + data; def encode_as_string(self): """Same as the encode_as_string method except it doesn't encode things as a JSON string""" + data = self.message; + if self.id is not None: + data = str(self.id) + self.message; + if self.path == "": - return str(self.type) + self.message; - return str(self.type) + self.path + "," + self.message; + return str(self.type) + data; + return str(self.type) + self.path + "," + data; + +def _is_integer(s): + try: + int(s); + except ValueError: + return False; + return True; def decode_message(payload): """ Decodes a message encoded via socket.io @@ -112,11 +148,15 @@ def decode_message(payload): i += len(path); if len(payload) > i: - # This is the same pecularity as above. - if "," in payload[i:]: - split_point = payload.index(","); - message_id = int(payload[i:split_point]); - i += split_point; + # This is another oddity. According to the socket.io-parser we + # need to loop over the next chars until we stop finding ints + # to determine if there is a message id. + message_id_str = ""; + while _is_integer(payload[i]): + message_id_str += payload[i]; + i += 1; + if message_id_str != "": + message_id = int(message_id_str); if len(payload) > i: message = payload[i:]; @@ -198,8 +238,3 @@ def encode_packet_string(code, path, data): """Encodes packet to be sent to socket.io server. """ - code_length = len(str(code)); - data_length = len(data); - length = code_length + data_length; - - return str(length) + ":" + str(code) + str(data); diff --git a/socketIO_client/transports.py b/socketIO_client/transports.py index 32a03f1..65be157 100644 --- a/socketIO_client/transports.py +++ b/socketIO_client/transports.py @@ -1,7 +1,7 @@ import json import logging import parser -from parser import Message, MessageType, PacketType +from parser import Message, Packet, MessageType, PacketType import re import requests import six @@ -75,18 +75,16 @@ class _AbstractTransport(object): self.send_packet(PacketType.MESSAGE, path, message.encode_as_json(), callback) def ack(self, path, packet_id, *args): - packet_id = packet_id.rstrip('+') - data = '%s+%s' % ( - packet_id, - json.dumps(args, ensure_ascii=False), - ) if args else packet_id - #self.send_packet(6, path, data) + _log.debug("[ack] Sending ACK for packet: %d" % packet_id); + message = Message(MessageType.ACK, "", path, "", packet_id); + packet = Packet(PacketType.MESSAGE, message); + self.send_engineio_packet(packet) def noop(self, path=''): self.send_packet(PacketType.NOOP, path) def send_packet(self, code, path='', data='', callback=None): - packet_text = parser.encode_packet_string(code, path, data); + packet_text = Packet(code, data).encode_as_string(); self.send(packet_text) _log.debug('[packet sent] %s', packet_text) @@ -140,11 +138,19 @@ class WebsocketTransport(_AbstractTransport): def connected(self): return self._connection.connected - def send_packet(self, code, path="", data='', callback=None): - packet_text = Message(code, data).encode_as_string(); + def send_message(self, message, callback = None): + packet_text = message.encode_as_string(); self.send(packet_text) _log.debug('[packet sent] %s', packet_text) + def send_engineio_packet(self, packet, callback=None): + packet_text = packet.encode_as_string(for_websocket = True); + self.send(packet_text) + _log.debug('[packet sent] %s', packet_text) + + def send_packet(self, code, path="", data='', callback=None): + self.send_message(Message(code, data), callback); + def send(self, packet_text): try: self._connection.send(packet_text)