Roy*_*mir 4 javascript server-sent-events signalr
signalR的后备之一是SSE - 服务器发送事件.它所做的就是通过这种结构发送消息:
Message\n\n
所以在服务器端:
Response.ContentType = "text/event-stream";
while (startDate.AddMinutes(1) > DateTime.Now)
{
Response.Write(string.Format("data: {0}\n\n", DateTime.Now.ToString()));
Response.Flush();
System.Threading.Thread.Sleep(1000);
}
Run Code Online (Sandbox Code Playgroud)
大.
但不是那么好.
我可以很容易地使用带有数据的JS命令(例如jsonp,也就是:使用回调对象类比填充),例如:_
cb(myMessage)
在客户端 - 同样处理它.(即使有更多欢迎mime类型,如application/javascript)
我可能在这里遗漏了一些东西.
服务器发送事件(SSE)相对于JSONP /长轮询的最大优点是,只要接收到块,就可以读取SSE响应的每个块,而不需要完成响应.
您可以使用分块响应来发回JSONP有效负载,但<script src="...负责加载JSONP有效负载的标记在整个响应完成之前不会执行JavaScript.实际上,这意味着每当使用JSONP向客户端发送消息时都必须完成响应,以便客户端可以立即读取消息.
这反过来意味着客户端必须为它接收的每条消息发出新的JSONP请求(即向文档添加新的脚本标记).这就是为什么JSONP被认为是长轮询的传输.
现在,正如您在其中一条评论中提到的,您可以使用iframe而不是脚本标记来加载JavaScript有效内容.如果这样做,您可以发送回chunked响应并在响应完成之前执行JavaScript,就像使用SSE一样.
实际上,这种隐藏的iframe技术正是SignalR用于永久帧传输的技术.不幸的是,这种技术有一些缺点导致SignalR在支持它的浏览器上更喜欢SSE:
隐藏的iframe技术需要一个相对沉重的前奏*,因为你实际上是发回一个HTML文档而不是纯JavaScript.
除函数调用外,每条消息都需要包装在自己的脚本块中.(例如<script>c({"message": "myMessage"})</script>).使用SSE,您只需要发送data: {"message": "myMessage"}\n\n效率稍高的数据.
最后,也许最重要的是,隐藏的iframe消耗的内存永远不会被清除,直到从DOM中删除.这意味着如果您不希望无限制的内存增长,则必须定期创建新的iframe并删除旧的iframe.SSE传输使用的EventSource对象可以无限期保持打开状态而不会泄漏内存.
*SignalR永远的框架前奏:
<!DOCTYPE html><html><head><title>SignalR Forever Frame Transport Stream</title>
<script>
var $ = window.parent.jQuery,
ff = $ ? $.signalR.transports.foreverFrame : null,
c = ff ? ff.getConnection('1') : null,
r = ff ? ff.receive : function() {};
ff ? ff.started(c) : '';</script></head><body>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
243 次 |
| 最近记录: |