据我所知,要建立一个事件流,必须在客户端上创建一个事件源对象,并将该对象的端点传递给服务器以向其注册。服务器在接收到此请求后,将适当地设置响应头,并按照事件流格式发送数据。我已经设置了此流程,并且可以通过http进行工作,但是将SSL添加到服务器后,将创建事件流,并且服务器将引发501-未实现错误。经过研究,我认为这可能是CORS问题,并添加了适当的标头,但这也没有任何区别。我还尝试了一些小的修复程序,这些修复程序通常可解决501错误,例如清除浏览器缓存和禁用任何代理设置。我对此完全感到困惑,如果有人可以帮助我理解问题以及解决问题的最佳方法,我将不胜感激。
编辑:
客户端通过aws elb负载均衡器向服务器发送请求,该负载均衡器从请求中剥离ssl并将请求转发至服务器。除了CORS相关问题外,服务器抛出501错误的另一个可能原因是请求已更改。
负载均衡器在将SSL转发到服务器之前从请求中删除SSL时,是否以某种方式更改sse请求,从而导致服务器抛出错误?一个人将如何监视进入负载均衡器的请求和转发的请求?另外,通过进一步研究,我了解到内部服务器端事件本质上是HTTP流的一种形式。即使在发送数据之后,该请求仍保持打开状态,直到客户端明确将其关闭为止。考虑到我的第一个直觉是错误的,因此将SSL剥离并转发到服务器而不更改请求,并且服务器发送响应标头和心跳信号以保持连接有效。
这是否意味着流也已加密?服务器是用Koa编写的。 sse注册端点如下所示:
// node.js
const SseStream = require('ssestream');
console.log('SseStream', SseStream)
const MyService = {
doSomeStuff: () => {return 222}
}
public async someFunctionInRouter(req,res) {
const origin = req.get('origin') || '';
const sseStream = new SseStream(req);
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.on('end', () => {
console.log("res.on('end'");
});
res.on('close', () => {
console.log("res.on('close'");
sseStream.unpipe(res);
});
res.on('error', ee => {
console.log("res.on('error'", ee);
sseStream.write({
id: 3,
event: 'myCustomEvent',
data: {
errors: [ee]
}
});
});
sseStream.pipe(res);
const result = await MyService.doSomeStuff(999, 888)
.catch(e => {
console.error('error', e);
sseStream.write({
id: 2,
event: 'myCustomEvent',
data: {
errors: [e]
}
});
});
sseStream.on('end', (eeee: any) => {
console.log('sseStream.on error', eeee);
});
sseStream.on('error', (eeee: any) => {
console.log('sseStream.on error', eeee);
});
sseStream.on('close', (eeee: any) => {
console.log('sseStream.on close', eeee);
});
sseStream.write({
id: 1,
event: 'myCustomEvent',
data: result
});
res.end();
}