Skip to content

Commit ee67edc

Browse files
author
Dave P
committed
add remaining bytes to queue if EAGAIN so as to not hog the event loop
1 parent 3f15476 commit ee67edc

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

SimpleWebSocketServer/SimpleWebSocketServer.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import sys
1313
import errno
1414
import codecs
15-
import Queue
15+
from collections import deque
1616
from BaseHTTPServer import BaseHTTPRequestHandler
1717
from StringIO import StringIO
1818
from select import select
@@ -81,7 +81,7 @@ def __init__(self, server, sock, address):
8181
self.frag_buffer = None
8282
self.frag_decoder = codecs.getincrementaldecoder('utf-8')(errors='strict')
8383
self.closed = False
84-
self.sendq = Queue.Queue()
84+
self.sendq = deque()
8585

8686
self.state = HEADERB1
8787

@@ -151,7 +151,7 @@ def _handlePacket(self):
151151
status = 1002
152152

153153
self.close(status, reason)
154-
raise Exception("received client close")
154+
#raise Exception("received client close")
155155

156156
if self.fin == 0:
157157
if self.opcode != STREAM:
@@ -245,7 +245,7 @@ def _handleData(self):
245245
if self.request.headers.has_key('Sec-WebSocket-Key'.lower()):
246246
key = self.request.headers['Sec-WebSocket-Key'.lower()]
247247
hStr = HANDSHAKE_STR % { 'acceptstr' : base64.b64encode(hashlib.sha1(key + GUID_STR).digest()) }
248-
self._sendBuffer(hStr)
248+
self.sendq.append((BINARY, hStr))
249249
self.handshaked = True
250250
self.headerbuffer = ''
251251
self.handleConnected()
@@ -280,7 +280,7 @@ def close(self, status = 1000, reason = u''):
280280
else:
281281
close_msg.extend(reason)
282282

283-
self._sendMessage(False, CLOSE, str(close_msg), False)
283+
self._sendMessage(False, CLOSE, str(close_msg))
284284

285285
finally:
286286
self.closed = True
@@ -289,24 +289,27 @@ def close(self, status = 1000, reason = u''):
289289
def _sendBuffer(self, buff):
290290
size = len(buff)
291291
tosend = size
292-
index = 0
292+
already_sent = 0
293293

294294
while tosend > 0:
295295
try:
296296
# i should be able to send a bytearray
297-
sent = self.client.send(buff[index:size])
297+
sent = self.client.send(buff[already_sent:])
298298
if sent == 0:
299299
raise RuntimeError("socket connection broken")
300300

301-
index += sent
301+
already_sent += sent
302302
tosend -= sent
303303

304304
except socket.error as e:
305305
# if we have full buffers then wait for them to drain and try again
306306
if e.errno == errno.EAGAIN:
307-
time.sleep(0.001)
307+
#time.sleep(0.001)
308+
return buff[already_sent:]
308309
else:
309310
raise e
311+
312+
return None
310313

311314
def sendFragmentStart(self, data):
312315
"""
@@ -353,7 +356,7 @@ def sendMessage(self, data):
353356
self._sendMessage(False, opcode, data)
354357

355358

356-
def _sendMessage(self, fin, opcode, data, useq = True):
359+
def _sendMessage(self, fin, opcode, data):
357360
header = bytearray()
358361
b1 = 0
359362
b2 = 0
@@ -387,10 +390,8 @@ def _sendMessage(self, fin, opcode, data, useq = True):
387390
else:
388391
payload = str(header)
389392

390-
if useq is True:
391-
self.sendq.put(payload)
392-
else:
393-
self._sendBuffer(payload)
393+
self.sendq.append((opcode, payload))
394+
394395

395396
def _parseMessage(self, byte):
396397
# read in the header
@@ -580,15 +581,24 @@ def close(self):
580581

581582
def serveforever(self):
582583
while True:
583-
rList, wList, xList = select(self.listeners, self.listeners, self.listeners, 1)
584+
rList, wList, xList = select(self.listeners, self.listeners, self.listeners, 3)
584585

585586
for ready in wList:
586587
client = None
587588
try:
588589
client = self.connections[ready]
589-
while not client.sendq.empty():
590-
client._sendBuffer(client.sendq.get())
590+
while client.sendq:
591+
opcode, payload = client.sendq.popleft()
592+
remaining = client._sendBuffer(payload)
593+
if remaining is not None:
594+
client.sendq.appendleft((opcode, remaining))
595+
break
596+
else:
597+
if opcode == CLOSE:
598+
raise Exception("received client close")
599+
591600
except Exception as n:
601+
592602
if client:
593603
client.client.close()
594604

0 commit comments

Comments
 (0)