From 40fec323ea50dfffb2bda2f52fb2c8ad9e265368 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 2 Nov 2007 23:04:19 -0800 Subject: [PATCH] improve SSDP a bit... send out multiple notifies... first is sometime between .5 and 1 seconds, and the second is between 1 and 5 seconds later... Also, schedule a resend of the notify for sometime between a third and a half of the max-age of it all... send out two byebye notifications just incase... Yes, this increases traffic, but it's required per the spec.. and w/ 100Mbit it's not too big of a deal.. [git-p4: depot-paths = "//depot/": change = 1088] --- SSDP.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/SSDP.py b/SSDP.py index bcff7ee..70fd5c2 100644 --- a/SSDP.py +++ b/SSDP.py @@ -37,18 +37,11 @@ class SSDPServer(DatagramProtocol): stdheaders = [ ('Server', 'Twisted, UPnP/1.0, python-upnp'), ] elements = {} known = {} - tasks = [] + maxage = 7 * 24 * 60 * 60 def doStop(self): '''Make sure we send out the byebye notifications.''' - while True: - try: - t = self.tasks.pop() - t.stop() - except IndexError: - break - for st in self.known.keys(): self.doByebye(st) del self.known[st] @@ -120,12 +113,16 @@ class SSDPServer(DatagramProtocol): self.known[st]['ST'] = st self.known[st]['EXT'] = '' self.known[st]['SERVER'] = 'Twisted, UPnP/1.0, python-upnp' - self.known[st]['CACHE-CONTROL'] = 'max-age=1800' - self.doNotify(st) + self.known[st]['CACHE-CONTROL'] = 'max-age=%d' % self.maxage + self.doNotifySchedule(st) - t = task.LoopingCall(lambda: self.doNotify(st)) - t.start(7 * 60) - self.tasks.append(t) + reactor.callLater(random.uniform(.5, 1), lambda: self.doNotify(st)) + reactor.callLater(random.uniform(1, 5), lambda: self.doNotify(st)) + + def doNotifySchedule(self, st): + self.doNotify(st) + reactor.callLater(random.uniform(self.maxage / 3, + self.maxage / 2), lambda: self.doNotifySchedule(st)) def doByebye(self, st): """Do byebye""" @@ -141,7 +138,9 @@ class SSDPServer(DatagramProtocol): del stcpy['ST'] resp.extend(map(lambda x: ': '.join(x), stcpy.iteritems())) resp.extend(('', '')) - self.transport.write('\r\n'.join(resp), (SSDP_ADDR, SSDP_PORT)) + resp = '\r\n'.join(resp) + self.transport.write(resp, (SSDP_ADDR, SSDP_PORT)) + self.transport.write(resp, (SSDP_ADDR, SSDP_PORT)) def doNotify(self, st): """Do notification"""