当前位置: 首页 > 知识库问答 >
问题:

是否可以对服务器发送事件(SSE)使用gzip压缩?

狄天逸
2023-03-14

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

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

但是我找不到任何带有gzip压缩的SSE示例。我尝试发送带有响应标头字段Content-Encode设置为“gzip”的gzip消息,但没有成功。

为了在SSE周围进行实验,我正在测试一个用Python制作的小型Web应用程序,其中包含瓶子框架gevent;我只是在运行瓶子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 html" target="_blank">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内容编码头字段的代码工作起来很有魅力。

编辑:感谢您的回复和另一个问题:Python:创建一个流gzip’d文件,如?,我设法解决了这个问题:

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

共有2个答案

郜修雅
2023-03-14

还可以使用中间件,这样就不必担心每个方法的gzip响应。这是我最近用过的一个。

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

这就是我使用它的方式(我正在使用bottle.py与gevent服务器)

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变量来设置要压缩的响应的w/c类型

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'])

所有响应都会通过中间件,并在不修改现有代码的情况下进行gzip处理。默认情况下,它压缩内容类型属于默认可压缩文件且内容长度大于200个字符的响应。

安奇
2023-03-14

TL;DR:如果请求没有缓存,您可能希望使用zlib并将内容编码声明为“deflate”。仅此更改就可以使代码正常工作。

如果将内容编码声明为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()

不过,这只有在使用实际文件作为缓存时才有意义。

 类似资料:
  • 我无法理解HTML5s服务器发送的事件是否真的适合ReST体系结构。我知道并非HTML5/HTTP的所有方面都需要适合ReST架构。但我想从专家那里知道HTTP的哪一半是SSE(ReSTful的一半还是另一半!)。 一种观点是它是ReSTful的,因为客户端向服务器发出了一个“初始”HTTP GET请求,其余的只能看作是不同内容类型的部分内容响应(“文本/事件流”) 发送的请求不知道有多少响应将作

  • 您好,我正在React中开发一个web应用程序,它使用Nginx从Express服务器接收SSE数据。 JS服务器 索引:JS const events=新事件源('https://api.myDomain.com/events', ); axios。post(<代码>https://api.myDomain.com/addCart,{客户端:this.state.clientId,购物车:car

  • 我正在尝试使用泽西岛的JavaScript SSE。我的资源中有以下代码。我在Java7和Tomcat 7上托管。我没有收到任何错误。但我也没有在页面上看到数据。 我调用发布数据。它确实显示信息。但客户什么都没有。在Firefox中,我确实看到事件多次触发。 这是我使用的参考。https://jersey.java.net/documentation/latest/sse.html 我的Index

  • 我有一个ASP。net core 3.1服务器项目,它有一个非常简单的API发送单向服务器发送事件(SSE),如下所示: 现在,我想通过C#UWP客户端接收这些事件。很遗憾,我只收到第一个事件: 如何在UWP中创建行为以始终监听该连接并接收我可以进一步处理的事件?

  • https://developer.mozilla.org/en-US/docs/Web/API/EventSource EventSource接口是web内容与服务器发送事件的接口。EventSource实例打开到HTTP服务器的持久连接,HTTP服务器以文本/事件流格式发送事件。通过调用EventSource,连接将保持打开状态,直到关闭。关闭()。 据我所知,服务器发送的事件需要持久的HTT

  • 我想要实现的是: user1向服务器发送消息(一个简单的POST请求) 服务器部分是(events.php) 我在(true)时尝试了无限循环以避免3秒的轮询。我也尝试过没有那个无限循环。只有发送消息的用户收到事件。 我理解这种做法并不好。但是,将SSE用于聊天应用程序的最佳实践是什么? 如何向所有用户发送事件?