2011-12-03 11 views
5

तो मैं जो कर रहा हूं वह एक डब्लूएसजीआई स्ट्रीमिंग सेवा लिख ​​रहा है जो एक मल्टीकास्ट पुश को लागू करने के लिए एक इटरेटर में लिपटे क्यू का उपयोग करता है। क्या इस प्रकार सेवा का एक सरलीकृत मॉडल है:एक डब्लूएसजीआई स्ट्रीमिंग सेवा को कार्यान्वित करना: (क्लाइंट डिस्कनेक्ट का पता लगाने के लिए कैसे)

# this is managed by another thread 
def processor_runner(): 
    generator = SerialMessageGenerator() 
    for message in generator: 
     for client in Processor.connections: 
      client.put(message) 

# this is managed by twisted's wsgi implementation 
def main(environ, start_response): 
    queue = Queue() 
    Processor.connections.append(queue) 
    status = '200 OK' 
    response_headers = [ 
     ('Content-Type', 'application/json'), 
     ('Transfer-Encoding', 'chunked') 
    ] 
    start_response(status, response_headers) 
    return iter(queue.get, None) 

और यह महान काम कर रहा है WSGI सर्वर के रूप में मुड़ के साथ (के रूप में एक अलग रूप में, सीरियल जनरेटर एक अलग प्रक्रिया एक अंतर प्रक्रिया कतार द्वारा प्रोसेसर से जुड़ा है) । मेरा सवाल यह है कि जब कोई क्लाइंट डिस्कनेक्ट करता है और इस तरह इसे कतार से हटा देता है तो मैं कैसे पता लगा सकता हूं? हालांकि, क्लाइंट सॉकेट i.e. (सॉकेट, कतार) के साथ एक कूप के रूप में कतार जोड़ रहा है और फिर यह जांच कर रहा है कि पॉट करने से पहले सॉकेट अभी भी जुड़ा हुआ है या नहीं। हालांकि, मुझे नहीं पता कि पर्यावरण से क्या पकड़ना है। इससे पहले कि मैं कुछ एक साथ हैक करने से पहले किसी को भी ऐसा करने का कोई अनुभव हो?

अपडेट किया गया

यहाँ समाधान मैं अंत में साथ चला गया है:

class IterableQueue(Queue): 

def __init__(self): 
    Queue.__init__(self) # Queue is an old style class 
    ShellProcessor.connections.append(self) 

def __iter__(self): 
    return iter(self.get, None) 

def close(self): 
    self.put(None) 
    self.task_done() 
    ShellProcessor.connections.remove(self) 
+0

इसके अलावा, अगर आप किसी भी अनुभव है वास्तुकला या एक WSGI स्ट्रीमिंग सेवा के प्रदर्शन पर टिप्पणी करने के लिए स्वतंत्र महसूस। – Bashwork

उत्तर

1

अगर अनुरोध समाप्त हो गया है या बाधित हो तो मौजूद है तो वर्तमान में .close() कॉलर इटेटर पर कॉल करें। आप की तरह कुछ कर सकता है:

# ... 
start_response(status, response_headers) 
return ResponseIterator(iter(queue.get, None), 
    on_finish=lambda: Processor.connections.remove(queue)) 

जहां ResponseIterator हो सकता है:

class ResponseIterator: 

    def __init__(self, iterator, on_finish=None): 
     self.iterator = iterator 
     self.on_finish = on_finish 

    def __iter__(self): 
     return self 

    def next(self): 
     return next(self.iterator) 

    def close(self): 
     if self.on_finish is not None: 
     self.on_finish() 
+0

अच्छा, मुझे नहीं पता था कि इसे इटरेटर पर बंद कहा जाता है। यह पूर्ण है! – Bashwork

संबंधित मुद्दे