解决http event stream一直卡到最后一个消息才一次性返回

发布时间:2024-04-05 20:19:00

我在用http event stream实现类似ChatGPT的打字机效果时遇到了这个问题:浏览器打开debug模式,看http event stream请求,EventStream直到最后一个消息发完才一直显示完所有消息。并不是请求失败,也不是没有响应,只是看起来像是卡住了,一直等到响应的数据全部接收完才一次性的回调onmessage方法。

没有什么是抓包分析不能解决的。

通过tcpdump抓包:

tcpdump -i any -w ./tcpdump3000.pcap 'tcp and port 3000'

然后使用Easy Tcp Analysis在线工具,将抓取的数据包上传分析。

开启压缩的http event stream抓包

上图为其中的一个event数据包的截图,可以看到,数据看着像是被加密处理过了。

但是我们没有做到任何的加密功能。唯一解释的通的,就是数据被压缩了。显示的配置关闭压缩后,再重新抓包分析。

关闭压缩的http event stream抓包

可以看到,这次数据包正常了。

所以原因是请求开启了压缩功能,响应的body被压缩了,所以在body没有接收完的情况下,是无法解析body的。我们只需要关闭压缩功能即可,配置compress为false。

如果是Vue3项目这样配置:

module.exports = defineConfig({
    transpileDependencies: true,
    devServer: {
        // 解决http event stream卡到最后一个消息才一次性返回的问题。
        compress: false,
        proxy: {
            '/api': {
                target: 'http://localhost:8090',
                changeOrigin: true
            }
        }
    },
})

如果是next.js项目这样配置:

/** @type {import('next').NextConfig} */
const nextConfig = {
    rewrites: async () => {
        return [
            {
                source: '/api/:path*',
                destination: process.env.PROXY_SERVER,
            },
        ];
    },
    // 解决http event stream卡到最后一个消息才一次性返回的问题。
    compress: false
}