2014-05-20 5 views
7

मैं जानना चाहता हूं कि सर्वर-प्रेषित घटनाओं (एसएसई; सामग्री-प्रकार: टेक्स्ट/ईवेंट-स्ट्रीम) के लिए gzip संपीड़न सक्षम करना संभव है या नहीं।क्या सर्वर-प्रेषित घटनाओं (एसएसई) के साथ gzip संपीड़न का उपयोग करना संभव है?

यह यह संभव है लगता है, इस पुस्तक के अनुसार: http://chimera.labs.oreilly.com/books/1230000000545/ch16.html

लेकिन मैं gzip संपीड़न के साथ SSE के किसी भी उदाहरण नहीं मिल सकता है। मैंने प्रतिक्रिया हेडर फ़ील्ड सामग्री-एन्कोडिंग सफलता के बिना "gzip" पर सेट किए गए gzipped संदेशों को भेजने की कोशिश की।

एसएसई के आसपास प्रयोग करने के लिए, मैं बोतल फ्रेमवर्क + गीवेंट के साथ पायथन में बने एक छोटे से वेब एप्लिकेशन का परीक्षण कर रहा हूं; मैं सिर्फ बोतल WSGI सर्वर चल रहा हूँ:

@bottle.get('/data_stream') 
def stream_data(): 
    bottle.response.content_type = "text/event-stream" 
    bottle.response.add_header("Connection", "keep-alive") 
    bottle.response.add_header("Cache-Control", "no-cache") 
    bottle.response.add_header("Content-Encoding", "gzip") 
    while True: 
     # new_data is a gevent AsyncResult object, 
     # .get() just returns a data string when new 
     # data is available 
     data = new_data.get() 
     yield zlib.compress("data: %s\n\n" % data) 
     #yield "data: %s\n\n" % data 

संपीड़न के बिना कोड (अंतिम पंक्ति, टिप्पणी की) और gzip बिना Content-Encoding शीर्षलेख क्षेत्र एक आकर्षण की तरह काम करता है।

संपादित: उत्तर के लिए और यह अन्य प्रश्न के लिए धन्यवाद: Python: Creating a streaming gzip'd file-like?, मैं समस्या को हल करने में कामयाब रहे:

@bottle.route("/stream") 
def stream_data(): 
    compressed_stream = zlib.compressobj() 
    bottle.response.content_type = "text/event-stream" 
    bottle.response.add_header("Connection", "keep-alive") 
    bottle.response.add_header("Cache-Control", "no-cache, must-revalidate") 
    bottle.response.add_header("Content-Encoding", "deflate") 
    bottle.response.add_header("Transfer-Encoding", "chunked") 
    while True: 
     data = new_data.get() 
     yield compressed_stream.compress("data: %s\n\n" % data) 
     yield compressed_stream.flush(zlib.Z_SYNC_FLUSH) 

उत्तर

4

टी एल; डॉ: अनुरोध कैश नहीं रहे हैं, तो आप की संभावना का उपयोग करना चाहते zlib और सामग्री-एन्कोडिंग को 'डिफ्लेट' घोषित करें। उस परिवर्तन को अकेले अपना कोड काम करना चाहिए।


यदि आप सामग्री-एन्कोडिंग को gzip होने की घोषणा करते हैं, तो आपको वास्तव में gzip का उपयोग करने की आवश्यकता है। वे एक ही संपीड़न एल्गोरिदम पर आधारित हैं, लेकिन gzip में कुछ अतिरिक्त फ़्रेमिंग है। यह काम करता है उदाहरण के लिए:

import gzip 
import StringIO 
from bottle import response, route 
@route('/') 
def get_data(): 
    response.add_header("Content-Encoding", "gzip") 
    s = StringIO.StringIO() 
    with gzip.GzipFile(fileobj=s, mode='w') as f: 
     f.write('Hello World') 
    return s.getvalue() 

यह केवल वास्तव में, यदि आप एक कैश के रूप में एक वास्तविक फ़ाइल का उपयोग करता है, तो समझ में आता है, हालांकि।

+0

आपकी व्याख्या के लिए धन्यवाद। दरअसल, डिफ्लेट करने के लिए सामग्री-एन्कोडिंग को बदलने में थोड़ा सा मदद मिलती है: पहला संदेश क्लाइंट साइड पर संसाधित होता है। लेकिन केवल पहला :(क्या आपको कोई विचार है? अग्रिम धन्यवाद – mguijarr

+0

क्या आप प्रत्येक डेटा ब्लॉक के लिए स्वतंत्र रूप से संपीड़ित कॉल करने का प्रयास कर रहे हैं? मुझे नहीं लगता कि यह काम करेगा। सभी डेटा एक संपीड़ित स्ट्रीम में होना चाहिए।इसका मतलब है कि अपने स्ट्रीमिंग इंटरफ़ेस के साथ gzip वास्तव में जाने का तरीका हो सकता है। हालांकि, मुझे विशिष्ट पॉइंटर्स प्रदान करने के लिए आपके अधिक कोड को देखना होगा। – otus

+0

धन्यवाद दस लाख; अंत में यह काम करता है! मैंने यह बताने के लिए अपना प्रश्न संपादित किया कि मुझे क्या बदलना है। – mguijarr

2

ऐसे मिडलवेयर भी हैं जिनका आप उपयोग कर सकते हैं ताकि आपको अपने प्रत्येक तरीके के लिए gzipping प्रतिक्रियाओं के बारे में चिंता करने की आवश्यकता न हो। यहां हाल ही में इस्तेमाल किया गया एक है।

https://code.google.com/p/ibkon-wsgi-gzip-middleware/

यह वह जगह है मैं इसे कैसे इस्तेमाल किया (मैं gevent सर्वर के साथ bottle.py उपयोग कर रहा हूँ)

from gzip_middleware import Gzipper 
import bottle 
app = Gzipper(bottle.app()) 
run(app = app, host='0.0.0.0', port=8080, server='gevent') 

इस विशेष पुस्तकालय के लिए, आप सेट कर सकते हैं डब्ल्यू/सी प्रतिक्रियाओं के प्रकार आप उदाहरण

DEFAULT_COMPRESSABLES = set(['text/plain', 'text/html', 'text/css', 
'application/json', 'application/x-javascript', 'text/xml', 
'application/xml', 'application/xml+rss', 'text/javascript',  
'image/gif']) 

सभी प्रतिक्रियाओं मिडलवेयर के माध्यम से जाने के लिए और अपने मौजूदा कोड को संशोधित करने के बिना gzipped पाने के लिए DEFAULT_COMPRESSABLES variable संशोधित करके सेक करना चाहते हैं। डिफ़ॉल्ट रूप से, यह उन प्रतिक्रियाओं को संपीड़ित करता है जिनकी सामग्री-प्रकार DEFAULT_COMPRESSABLES से संबंधित है और जिनकी सामग्री-लंबाई 200 वर्णों से अधिक है।

+0

आपके उत्तर के लिए धन्यवाद – mguijarr

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