<p>最后,当数据到达时,我维护了一个推迟回调的列表,并缓冲传入的数据,直到它满足列表中第一个推迟回调所需的数据长度。你知道吗</p>
<pre><code>class SomeProtocol(Protocol):
# initialise self.buf and self.readers in __init__
def deferred_read(self, count, timeout=None):
"""Return a deferred that fires when data becomes available"""
d = defer.Deferred()
reader = [d, count]
timeout_cb = None
if timeout is not None:
timeout_cb = self.reactor.callLater(timeout, self.deferred_read_timeout, reader)
reader.append(timeout_cb)
self.readers.append(reader)
self.check_readers()
return d
def deferred_read_timeout(self, reader):
"""Timeout this reader and check if others now match"""
d, count, timeout_cb = reader
self.readers.remove(reader)
d.errback(TimeoutException()) # defined elsewhere
self.check_readers()
def check_readers(self):
"""Check if there is enough data to satisfy first reader"""
try:
while 1:
reader = self.readers[0]
d, count, timeout_cb = reader
if len(self.buf) < count:
break
data = self.buf[:count]
self.buf = self.buf[count:]
self.readers.remove(reader)
try:
timeout_cb.cancel()
except: pass
d.callback(data)
except IndexError: pass
def dataReceived(self, data):
self.buf += data
self.check_readers()
</code></pre>
<p>它当前要求count为非零。最好扩展它以支持返回当前在读取缓冲区中的内容,并在有超时但不计数的情况下读取,以便在超时后返回缓冲区中的内容。你知道吗</p>