diff --git a/websocket.py b/websocket.py index 7ff057d..54c63f0 100644 --- a/websocket.py +++ b/websocket.py @@ -13,7 +13,10 @@ along with this program. If not, see """ -import sys, re, urlparse, socket, asyncore +import sys, re, urlparse, socket, asyncore, threading + +urlparse.uses_netloc.append("ws") +urlparse.uses_fragment.append("ws") class WebSocket(object): def __init__(self, url, **kwargs): @@ -28,8 +31,8 @@ def __init__(self, url, **kwargs): self._dispatcher = _Dispatcher(self) - def send(self, data): - self._dispatcher.write('\x00' + _utf8(data) + '\xff') + def send(self, data,sync=False): + self._dispatcher.write('\x00' + _utf8(data) + '\xff',sync) def close(self): self._dispatcher.handle_close() @@ -81,20 +84,23 @@ def _str_(self): class _Dispatcher(asyncore.dispatcher): def __init__(self, ws): + self.lock = threading.Lock() #threadsafe addon + asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect((ws.host, ws.port)) self.ws = ws self._read_buffer = '' - self._write_buffer = '' + with self.lock: #threadsafe addon + self._write_buffer = '' self._handshake_complete = False - + if self.ws.port != 80: hostport = '%s:%d' % (self.ws.host, self.ws.port) else: hostport = self.ws.host - + fields = [ 'Upgrade: WebSocket', 'Connection: Upgrade', @@ -133,7 +139,9 @@ def handle_close(self): self.close() if self.ws.onclose: self.ws.onclose() - + def handle_connect (self): + pass + def handle_read(self): if self._handshake_complete: self._read_until('\xff', self._handle_frame) @@ -141,20 +149,27 @@ def handle_read(self): self._read_until('\r\n\r\n', self._handle_header) def handle_write(self): - sent = self.send(self._write_buffer) - self._write_buffer = self._write_buffer[sent:] + with self.lock: #threadsafe addon + sent = self.send(self._write_buffer) + self._write_buffer = self._write_buffer[sent:] def writable(self): - return len(self._write_buffer) > 0 + with self.lock: #threadsafe addon + return len(self._write_buffer) > 0 - def write(self, data): - self._write_buffer += data # TODO: separate buffer for handshake from data to - # prevent mix-up when send() is called before - # handshake is complete? + def write(self, data,sync=False): + with self.lock: #threadsafe addon + self._write_buffer += data # TODO: separate buffer for handshake from data to + # prevent mix-up when send() is called before + # handshake is complete? + if sync: + self.handle_write() def _read_until(self, delimiter, callback): self._read_buffer += self.recv(4096) - pos = self._read_buffer.find(delimiter)+len(delimiter)+1 + pos = self._read_buffer.find(delimiter) + if pos >= 0: + pos += len(delimiter) if pos > 0: data = self._read_buffer[:pos] self._read_buffer = self._read_buffer[pos:] @@ -226,3 +241,4 @@ def _cookie_for_domain(cookie, domain): def _utf8(s): return s.encode('utf-8') +