使用ServiceStack的服务器事件功能如果不涉及跨源HTTP请求,我可以同步两个浏览器。它的工作原理与文档一样简单:
(1)Plugins.Add(new ServerEventsFeature());
(2)SyncRequest端点:
[Route("/channels/{Channel}/sync", "POST")]
public class SyncRequest : IReturnVoid
{
public string From { get; set; }
public string ToUserId { get; set; }
public string Channel { get; set; }
public string Message { get; set; }
public string Selector { get; set; }
}
public class SyncService : Service
{
public IServerEvents ServerEvents { get; set; }
public void Any(SyncRequest request)
{
ServerEvents.NotifyChannel(request.Channel, "sync", request.From);
}
}
(3)在浏览器中:
var mychannel = 'example';
var source= new EventSource(`${serviceUrl}/event-stream?channel={mychannel}`);
source.onmessage = (m) => {}; // etc.
有了这个,我可以通过调用SyncRequest端点(在一个浏览器中)并在另一个浏览器中处理来自EventSource的消息来同步浏览器。
但是 ,如果同步服务器位于另一个域上且需要跨源HTTP请求,则会失败。
Plugins.Add(new CorsFeature(...))
似乎在一段时间后有效,但在Chrome中(在Linux上)我首先在控制台中看到ERR_INVALID_CHUNKED_ENCODING错误。
在互联网上,我看到有人认为Chrome是严格的w.r.t. chunked编码,这可能会导致这些ERR_INVALID_CHUNKED_ENCODING错误。我还看到对/ event-stream调用的响应有Transfer-Encoding:chunked
标题,但我不知道这是否确实是原因,如果是,如何摆脱它。
在another question on ServiceStack's SSE plus CORS mythz
中建议可以像这样更改响应标头:
Plugins.Add(new ServerEventsFeature {
OnInit = request => {
request.Response.AddHeader("Transfer-Encoding", "identity");
},
OnHeartbeatInit = request => {
request.Response.AddHeader("Transfer-Encoding", "identity");
}
});
但这对/event-stream?channel=example
调用没有影响 - 其响应标头包含Transfer-Encoding:chunked
(默认情况下心跳为Transfer-Encoding:identity
。
现在浏览器一直在尝试使用/event-stream?channel=example
重新建立连接,并且第一次成功时我们很好 - EventSource对象工作,心跳发生,并且可以进行同步。
我正在使用ServiceStack / 4.512 NET45 Unix / Mono。
所以问题是:有没有办法在没有ERR_INVALID_CHUNKED_ENCODING错误的情况下立即建立SSE连接?也许ServiceStack有common error referred to in another question?
答案 0 :(得分:1)
Chunked Transfer-Encoding是正常的,其长度未知。问题很可能是由Mono的HTTP实施引起的,如果您在Linux / OSX上运行,建议{@ 3}}使用,这是受支持的选项。