Added more documentation
This commit is contained in:
parent
2361706c4e
commit
455890a700
2 changed files with 62 additions and 12 deletions
|
|
@ -16,7 +16,6 @@ except ImportError:
|
|||
from .exceptions import ConnectionError, TimeoutError, PacketError
|
||||
from .transports import _get_response
|
||||
|
||||
|
||||
_SocketIOSession = namedtuple('_SocketIOSession', [
|
||||
'id',
|
||||
'heartbeat_interval',
|
||||
|
|
@ -24,7 +23,6 @@ _SocketIOSession = namedtuple('_SocketIOSession', [
|
|||
'server_supported_transports',
|
||||
])
|
||||
_log = logging.getLogger(__name__)
|
||||
PROTOCOL_VERSION = 1
|
||||
RETRY_INTERVAL_IN_SECONDS = 1
|
||||
|
||||
class BaseNamespace(object):
|
||||
|
|
@ -171,6 +169,9 @@ class SocketIO(object):
|
|||
self._terminate_heartbeat();
|
||||
|
||||
def _terminate_heartbeat(self):
|
||||
"""Terminates the heartbeat thread.
|
||||
|
||||
"""
|
||||
if self.heartbeat_terminator is not None:
|
||||
self.heartbeat_terminator.set();
|
||||
self.heartbeat_thread.join();
|
||||
|
|
@ -365,6 +366,21 @@ class SocketIO(object):
|
|||
return self.__transport
|
||||
|
||||
def _upgrade(self):
|
||||
"""Attempts to upgrade the connection to a websocket.
|
||||
|
||||
This method will execute the update process outline here:
|
||||
https://github.com/Automattic/engine.io-protocol#transport-upgrading
|
||||
|
||||
To summarize, we first send a PING packet with the string
|
||||
'probe' appended as data. This signals to the server that we
|
||||
want to probe the ability to upgrade. If the server has this
|
||||
functionality, it responds with a PONG packet and the 'probe'
|
||||
string.
|
||||
|
||||
We then send an UPGRADE packet, restart the heartbeat thread,
|
||||
and return.
|
||||
|
||||
"""
|
||||
websocket = transports.WebsocketTransport(self.session, self.is_secure, self.base_url, **self.kw);
|
||||
websocket.send_packet(PacketType.PING, "", "probe");
|
||||
for packet in websocket.recv_packet():
|
||||
|
|
@ -384,6 +400,19 @@ class SocketIO(object):
|
|||
return websocket;
|
||||
|
||||
def _start_heartbeat(self, transport):
|
||||
"""Starts the heartbeat thread.
|
||||
|
||||
The heartbeat thread ensures that our connection is never
|
||||
severed. This effectively spawns a thread that sits in an
|
||||
infinite loop. The thread waits
|
||||
self.session.heartbeat_interval / 2 (gleaned from the server)
|
||||
seconds, then sends a heartbeat packet (PING).
|
||||
|
||||
The thread is implemented using a multiprocessing.Event to
|
||||
perform the wait, so it doesn't waste any cpu cycles while
|
||||
it's waiting.
|
||||
|
||||
"""
|
||||
_log.debug("[start heartbeat pacemaker]");
|
||||
self.heartbeat_terminator = multiprocessing.Event();
|
||||
self.heartbeat_thread = multiprocessing.Process(
|
||||
|
|
@ -458,10 +487,14 @@ class SocketIO(object):
|
|||
find_event_callback('disconnect')()
|
||||
|
||||
def _on_event(self, packet, find_event_callback):
|
||||
# Accoding to the documentation
|
||||
# (https://github.com/automattic/socket.io-protocol#event),
|
||||
# the event name is the first entry in the message array, and
|
||||
# the arguments are the rest of the entries.
|
||||
"""This delegate is called when there is an EVENT packet.
|
||||
|
||||
Accoding to the documentation
|
||||
(https://github.com/automattic/socket.io-protocol#event), the
|
||||
event name is the first entry in the message array, and the
|
||||
arguments are the rest of the entries.
|
||||
|
||||
"""
|
||||
event = packet.payload.message[0];
|
||||
args = packet.payload.message[1:] if len(packet.payload.message) > 1 else [];
|
||||
|
||||
|
|
@ -556,7 +589,7 @@ def _yield_elapsed_time(seconds=None):
|
|||
|
||||
def _get_socketIO_session(is_secure, base_url, **kw):
|
||||
server_url = '%s://%s/?EIO=%d&transport=polling' \
|
||||
% ('https' if is_secure else 'http', base_url, parser.ENGINE_PROTOCOL)
|
||||
% ('https' if is_secure else 'http', base_url, parser.ENGINEIO_PROTOCOL)
|
||||
_log.debug('[session] %s', server_url)
|
||||
try:
|
||||
response = _get_response(requests.get, server_url, **kw)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import json
|
|||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
ENGINE_PROTOCOL = 3;
|
||||
ENGINEIO_PROTOCOL = 3;
|
||||
|
||||
class PacketType(Enum):
|
||||
OPEN = 0;
|
||||
|
|
@ -25,6 +25,8 @@ class MessageType(Enum):
|
|||
BINARY_ACK = 6;
|
||||
|
||||
class Packet():
|
||||
""" Represents a 'packet' from the engine.io protocol.
|
||||
"""
|
||||
def __init__(self, packet_type, payload):
|
||||
self.type = packet_type;
|
||||
self.payload = payload;
|
||||
|
|
@ -33,6 +35,16 @@ class Packet():
|
|||
return "PACKET{type: " + str(self.type) + ", payload: " + str(self.payload) + "}";
|
||||
|
||||
def encode_as_string(self, for_websocket = False):
|
||||
"""Returns the packet encoded according to the engine.io-protocol.
|
||||
|
||||
Reference: (https://github.com/Automattic/engine.io-protocol).
|
||||
|
||||
It's worth noting that websockets have their own framing and
|
||||
encoding mechanism so if the packet is going to be transmitted
|
||||
via websockets, we encode it slightly differently per the
|
||||
documentation.
|
||||
|
||||
"""
|
||||
data = "";
|
||||
path = "";
|
||||
if self.type == PacketType.MESSAGE and not isinstance(self.payload, basestring):
|
||||
|
|
@ -54,6 +66,8 @@ class Packet():
|
|||
return encoded;
|
||||
|
||||
class Message():
|
||||
"""Represents a 'message' from the socket.io protocol.
|
||||
"""
|
||||
def __init__(self, message_type, message, path = "", attachments = "", message_id = None):
|
||||
self.type = message_type;
|
||||
if isinstance(message, basestring):
|
||||
|
|
@ -84,9 +98,8 @@ class Message():
|
|||
"}";
|
||||
|
||||
def encode_as_json(self):
|
||||
"""Encodes a Message to be sent to socket.io server.
|
||||
|
||||
Assumes the message payload will be dumped as a json string.
|
||||
"""Encodes a JSON Message to be sent to socket.io server.
|
||||
|
||||
"""
|
||||
data = json.dumps(self.message);
|
||||
if self.id is not None:
|
||||
|
|
@ -97,7 +110,11 @@ class Message():
|
|||
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"""
|
||||
"""Encodes a Message to be to a socket.io server.
|
||||
|
||||
This will call encode_as_json if the message is not a string.
|
||||
|
||||
"""
|
||||
if not isinstance(self.message, basestring):
|
||||
return self.encode_as_json();
|
||||
data = self.message;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue