2017-12-28 31 views
6

मैं django के साथ आंतरिक http सेवाओं से कनेक्ट करना चाहता हूं और मुझे आउटपुट को उन सेवाओं के http प्रतिक्रिया को बफर करना होगा क्योंकि कुछ सामग्री बहुत बड़ी हैं।Iterable ऑब्जेक्ट और Django StreamingHttpResponse

मैं अजगर 3.6, Django 2.0, http.client उपयोग कर रहा हूँ और निम्नलिखित कोड:

class HTTPStreamIterAndClose(): 
    def __init__(self, conn, res, buffsize): 
     self.conn = conn 
     self.res = res 
     self.buffsize = buffsize 
     self.length = 1 

     bytes_length = int(res.getheader('Content-Length')) 

     if buffsize < bytes_length: 
      self.length = math.ceil(bytes_length/buffsize) 

    def __iter__(self): 
     return self 

    def __next__(self): 
     buff = self.res.read(self.buffsize) 

     if buff is b'': 
      self.res.close() 
      self.conn.close() 

      raise StopIteration 
     else: 

      return buff 

    def __len__(self): 
     return self.length 


def passthru_http_service(request, server, timeout, path): 
    serv = HTTPService(server, timeout) 
    res = serv.request(path) 

    response = StreamingHttpResponse(
     HTTPStreamIterAndClose(serv.connection, res, 200), 
     content_type='application/json' 
    ) 
    response['Content-Length'] = res.getheader('Content-Length') 

    return response 

और प्रतिक्रिया खाली है, मैं साथ इटरेटर का परीक्षण:

b''.join(HTTPStreamIterAndClose(serv.connection, res, 200) 

और सब कुछ ठीक काम करता है, मुझे नहीं पता क्यों काम नहीं कर रहा है।

+0

क्या ब्राउज़र कंसोल में कोई त्रुटि है? – xyres

+0

नहीं, कोई त्रुटि नहीं है –

+0

आपका क्या मतलब है "काम नहीं कर रहा"? क्या आपको http 500 मिलता है? एक खाली उत्पादन के साथ 200? कृपया अपने प्रश्न में 'curl -v http: // localhost: 8000/x/y /' (या पोस्टमैन या ...) आउटपुट प्रदान करें। –

उत्तर

4

https://andrewbrookins.com/django/how-does-djangos-streaminghttpresponse-work-exactly/

सबसे पहले, कुछ की स्थिति सही होना चाहिए:

  • ग्राहक बोल जाना चाहिए HTTP/1.1 या नए
  • अनुरोध विधि एक HEAD
  • प्रतिक्रिया नहीं करता था Content-Length हेडर
  • शामिल नहीं है प्रतिसाद स्थिति नहीं 204 या 304

इन शर्तों के सत्य हैं, तो Gunicorn जवाबी कार्रवाई के लिए एक Transfer-Encoding: chunked हैडर जोड़ना होगा, ग्राहक है कि प्रतिक्रिया मात्रा में धारा जाएगा संकेत था।

वास्तव में, Transfer-Encoding: chunked के साथ गनिकॉर्न प्रतिक्रिया देगा, भले ही यदि आप उन शर्तों के सत्य हैं, तो आप एक HttpResponse का उपयोग करते हैं!

वास्तव में प्रतिक्रिया को स्ट्रीम करने के लिए, टुकड़ों में क्लाइंट को भेजने के लिए, शर्तों को सत्य होना चाहिए, और आपकी प्रतिक्रिया को एकाधिक आइटमों के साथ पुन: प्रयोज्य होने की आवश्यकता है।

असल में, आपको यह तय करने की आवश्यकता है: स्ट्रीमिंग या Content-Length

यदि आप पुन: प्रारंभ करने योग्य डाउनलोड Range का उपयोग करना चाहते हैं।

+0

क्या यह अन्य डब्लूएसजीआई सर्वर पर भी लागू होता है? – dahrens

+0

आईडीके, मैंने प्रयोग नहीं किया था। –

0

अंत में, समस्या इस तथ्य में थी कि http अनुरोध कुछ एमएस के बाद डिस्कनेक्ट हो जाता है, यही कारण है कि जब मैं कनेक्शन के बाद तत्काल पुन: प्रयास करता हूं और वस्तुओं के निर्माण से पहले काम करता हूं और प्रतिक्रिया के बाद उपयोग नहीं करता , लेकिन जब मैं फिर से शुरू करने के लिए कनेक्शन शुरू करता हूं, तो सभी पूरी तरह से काम करते हैं = /।

चीयर्स।

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