是否可以将gzip压缩与服务器发送事件(SSE)一起使用? [英] Is it possible to use gzip compression with Server-Sent Events (SSE)?

查看:220
本文介绍了是否可以将gzip压缩与服务器发送事件(SSE)一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否可以为服务器发送事件启用gzip压缩
(SSE;内容类型:文本/事件流)。



根据这本书,似乎有可能:
http://chimera.labs.oreilly.com/books/1230000000545/ch16.html



但我找不到任何SSE的例子gzip压缩。我试图
发送gzipped消息,响应头字段
Content-Encoding 设置为gzip但没有成功。



<为了试验SSE,我正在使用瓶子框架+ gevent测试一个用Python制作的小型Web应用程序
;我正在运行
瓶子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)
而True:
#new_data是一个gevent AsyncResult对象,
#.get()只在新的
#数据可用时返回数据字符串
data = new_data.get()
yield zlib.compress(data :%s \ n \ n%data
#yielddata:%s \ n \ n%data

没有压缩的代码(最后一行,已注释)且没有gzip
内容编码标题字段就像魅力一样。



编辑:感谢回复和其他问题: Python:创建流媒体gzip文件?,我设法解决了这个问题:

  @ 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)
而True:
data = new_data.get()
yield compressed_stream.compress(data:%s\\\
\ n%data)
yield compressed_stream.flush(zlib .Z_SYNC_FLUSH)


解决方案

TL; DR:如果请求是如果没有缓存,您可能希望使用zlib并声明Content-Encoding为'deflate'。仅此更改应该可以使您的代码正常工作。






如果您将Content-Encoding声明为gzip,则需要实际使用gzip的。它们基于相同的压缩算法,但gzip有一些额外的框架。这有效,例如:

  import gzip 
从瓶子导入响应导入StringIO
,路由
@route('/')
def get_data():
response.add_header(Content-Encoding,gzip)
s = StringIO.StringIO()
用gzip.GzipFile(fileobj = s,mode ='w')作为f:
f.write('Hello World')
返回s.getvalue()

但是,如果你使用实际文件作为缓存,这才有意义。


I would like to know if it is possible to enable gzip compression for Server-Sent Events (SSE ; Content-Type: text/event-stream).

It seems it is possible, according to this book: http://chimera.labs.oreilly.com/books/1230000000545/ch16.html

But I can't find any example of SSE with gzip compression. I tried to send gzipped messages with the response header field Content-Encoding set to "gzip" without success.

For experimenting around SSE, I am testing a small web application made in Python with the bottle framework + gevent ; I am just running the bottle WSGI server:

@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

The code without compression (last line, commented) and without gzip content-encoding header field works like a charm.

EDIT: thanks to the reply and to this other question: Python: Creating a streaming gzip'd file-like?, I managed to solve the problem:

@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)

解决方案

TL;DR: If the requests are not cached, you likely want to use zlib and declare Content-Encoding to be 'deflate'. That change alone should make your code work.


If you declare Content-Encoding to be gzip, you need to actually use gzip. They are based on the the same compression algorithm, but gzip has some extra framing. This works, for example:

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()

That only really makes sense if you use an actual file as a cache, though.

这篇关于是否可以将gzip压缩与服务器发送事件(SSE)一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆