首页 > 解决方案 > 通过 https 建立 SSE 连接失败

问题描述

据我所知,要建立一个事件流,必须在客户端上创建一个事件源对象,将其传递给服务器以注册自身。服务器收到此请求后,适当地设置响应标头并按照事件流格式发送数据。我已经设置了这个流程,它通过 http 工作,但是在将 SSL 添加到服务器之后,正在创建事件流并且服务器抛出 501 - 未实现错误。经过一些研究,我认为这可能是一个 CORS 问题并添加了适当的标题,但这也没有任何区别。我还尝试了通常适用于 501 错误的小修复,例如清除浏览器缓存和禁用任何代理设置。我'

编辑:

客户端通过 aws elb 负载均衡器向服务器发送请求,该负载均衡器从请求中剥离 ssl 并将请求转发到服务器。除了 CORS 相关问题之外,服务器抛出 501 错误的另一个可能原因是请求已更改。

此外,经过进一步研究,我了解到内部服务器端事件本质上是 HTTP 流的一种形式。即使在发送数据之后,请求也会保持打开状态,直到客户端明确关闭它。考虑到我的第一个预感是错误的,SSL 被剥离并转发到服务器而不更改请求,服务器发送响应标头和心跳信号以保持连接处于活动状态。

服务器是用 Koa 编写的。这是 sse 注册端点的样子:

router.get("/api/sse/register/*", async (ctx: Router.IRouterContext) => {
        const i = ctx.path.lastIndexOf("/");
        const asset: string = ctx.path.slice(18, i);
        const orgId: string = ctx.path.slice(i + 1);
        let assetObj: any = myCache.get(asset);

        // setting headers to specify event stream connection
        ctx.set({
            "Access-Control-Allow-Origin" : "*",
            "Content-Type" : "text/event-stream; charset=utf-8",
            "Cache-Control" : "no-cache",
            "Connection" : "Keep-Alive",
            "Transfer-encoding": "identity",
        });
        ctx.status = 200;
        ctx.flushHeaders();

        /* Creating pass through stream that simply pipes input given to it to its assigned output stream which in this case is ctx.body*/
        const stream = new PassThrough();
        ctx.body = stream;
        // saving mapping between orgId and its stream object to push data to
        assetObj[orgId] = stream;
        myCache.set(asset, assetObj);
        sendHeartbeatSignal(orgId, asset, assetObj);
 }

这也是 sse 事务的客户端的样子:

const source = new EventSource("/api/sse/register/trailers/" + org.id);
source.addEventListener("message", (event: any) => this.onUpdate(this, event));

标签: httpsserver-sent-events

解决方案


推荐阅读