通过https建立SSE连接失败

通过https建立SSE连接失败,https,server-sent-events,Https,Server Sent Events,据我所知,要建立一个事件流,必须在客户机上创建一个事件源对象,将端点传递给服务器,以便向其注册。服务器在收到此请求时,会适当地设置响应头,并按照事件流格式发送数据。我已经设置了这个流,它通过http工作,但是在向服务器添加SSL之后,事件流被创建,服务器抛出一个501-未实现的错误。经过一些研究,我认为这可能是一个CORS问题,并添加了适当的标题,但这也没有什么区别。我还尝试了一些小的修复,这些修复通常适用于501个错误,比如清除浏览器缓存和禁用任何代理设置。我对此完全感到困惑,如果有人能帮助我

据我所知,要建立一个事件流,必须在客户机上创建一个事件源对象,将端点传递给服务器,以便向其注册。服务器在收到此请求时,会适当地设置响应头,并按照事件流格式发送数据。我已经设置了这个流,它通过http工作,但是在向服务器添加SSL之后,事件流被创建,服务器抛出一个501-未实现的错误。经过一些研究,我认为这可能是一个CORS问题,并添加了适当的标题,但这也没有什么区别。我还尝试了一些小的修复,这些修复通常适用于501个错误,比如清除浏览器缓存和禁用任何代理设置。我对此完全感到困惑,如果有人能帮助我理解这个问题以及解决问题的最佳方法,我将不胜感激

编辑:

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

  • 负载平衡器在将请求转发到服务器之前从请求中删除SSL时,是否可能以某种方式更改sse请求,从而导致服务器抛出错误?如何监控进入负载平衡器的请求和转发的请求
此外,经过进一步研究,我了解到服务器端事件本质上是HTTP流的一种形式。即使在发送数据之后,请求仍保持打开状态,直到客户端显式关闭为止。考虑到我的第一个预感是错误的,SSL被剥离并转发到服务器,而不改变请求,服务器发送响应头和心跳信号以保持连接活动

  • 这是否意味着流也被加密了

服务器是用膝关节炎书写的。以下是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);
 }
const source = new EventSource("/api/sse/register/trailers/" + org.id);
source.addEventListener("message", (event: any) => this.onUpdate(this, event));
此外,苏格兰和南方能源公司交易的客户端是这样的:

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);
 }
const source = new EventSource("/api/sse/register/trailers/" + org.id);
source.addEventListener("message", (event: any) => this.onUpdate(this, event));

你能举个实际的例子吗。或者至少解释一下你是怎么解决CORS的?另外,您使用了哪些服务器和哪些操作系统/浏览器?最后(目前!),它是一个自签名SSL证书吗?(浏览器问题是关键问题:它在所有浏览器中失败,而只是在浏览器中失败)。我用膝关节炎(KoA)编写了服务器,目前它在AWS上托管,我只尝试过在Ubuntu和Chrome上运行它。我没有在不同的浏览器上试用它的原因是我没有实现polyfill for sse在所有浏览器中都能工作。我现在只是想让它在Chrome上运行。不,它不是自签名证书。它部署在位于客户端和服务器之间的aws负载平衡器上instance@DarrenCook我在最新的编辑中加入了一些代码