免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4287 | 回复: 1
打印 上一主题 下一主题

HTTP 2.0 服务器推送技术的创新 [复制链接]

论坛徽章:
49
15-16赛季CBA联赛之福建
日期:2016-06-22 16:22:002015年亚洲杯之中国
日期:2015-01-23 16:25:12丑牛
日期:2015-01-20 09:39:23未羊
日期:2015-01-14 23:55:57巳蛇
日期:2015-01-06 18:21:36双鱼座
日期:2015-01-02 22:04:33午马
日期:2014-11-25 09:58:35辰龙
日期:2014-11-18 10:40:07寅虎
日期:2014-11-13 22:47:15申猴
日期:2014-10-22 15:29:50摩羯座
日期:2014-08-27 10:49:43辰龙
日期:2014-08-21 10:47:58
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-06-19 09:35 |只看该作者 |倒序浏览
HTTP 2.0 允许服务器为一次客户端请求发送多个响应(并行的) - 即, 服务器推送。等等,我们为什么想要这样? 是这样的,一个一般的网页需要一堆的额外资源,比如JavaScript,CSS,和图片, 对这些资源的引用就内置在服务器产生的HTML页面里。那么,与其等待客户端去发现对这些资源的引用,为什么不让服务器立即把这些资源都发送过去呢?服务器推送可以消除这种不必要的网络等待所带来的整个往返耗时。

事实上,如果你曾经内联的引用过一个资源(CSS, JS,或者一个图片),那么你已经“模拟”过服务器推送:一个内联资源被作为父文档的一部分“推送”过来。唯一的不同是HTTP 2.0使得这一模式更有效而且更强大!


着手进行HTTP 2.0服务器推送
一个内联的资源,从定义上说,是父文档的一部分。那么,它就不能被独立的缓存,并且它需要在许多不同的页面之间被复制 - 这是很低效的。相反的,推送的资源可以被浏览器独立的缓存起来,从而在许多页面中复用。这里准备了一个例子:
        
spdy.createServer(options, function(req, res) {
  // push JavaScript asset (/main.js) to the client
  res.push('/main.js', {'content-type': 'application/javascript'}, function(err, stream) {
    stream.end('alert("hello from push stream!")');
  });
  // write main response body and terminate stream
  res.end('Hello World! ');
}).listen(443);
            
上例中,我们有一个借助于node-spdy module实现的最简SPDY服务,它对所有的入站请求的响应是,输出一个字符串"Hello World!",跟着是一个脚本标记。除此之外,我们还做了些聪明的事情: 我们推送“main.js”文件到客户端,该文件触发了一个JavaScript弹出框。
结果是,当浏览器发现HTML响应中的脚本标记时,“main.js”文件已经在缓存中了,不会发生额外的网络往返!HTTP 2.0 服务器推送 废弃了内联引用。最重要的是,服务器推送已经被所有的支持SPDY的浏览器所支持(Firefox,Opera,和Chrome)。
            
我们还能推送什么?
用服务器推送替换内嵌资源是一个典型例子。但是,为什么止步于此,我们还能推送什么? 其实, 任何HTTP响应都是平等的游戏。我们能推送一次重定向吗? 是的, 那很简单:
   
spdy.createServer(options, function(req, res) {
  //push JavaScript asset (/newasset.js) to the client
  res.push('/newasset.js', {'content-type': 'application/javascript'}, function(err, stream) {
    stream.end('alert("hello from (redirected) push stream!")');
  });
  // push 301 redirect: /asset.js -> /newasset.js
  res.push('/asset.js', {':status': 301, 'Location': '/newasset.js'}, function(err, stream) {
    stream.end('301 Redirect');
  });
  // write main response body and terminate stream
  res.end('');
}).listen(443);
            
跟上面的例子一样,只不过我们已经把“asset.js”资源替换为一次对“newasset.js”文件的301重定向。浏览器对重定向和“asset.js”都进行了缓存,并且在无任何额外网络往返的情况下执行脚本。怎么应用?我把这个问题留给读者当练习吧。
            
我们还能做的更多吗?推送缓存失效信息和再验证信息到客户端,怎么样?我们可以把已经存在于客户端缓存中的任何资源标记为失效(即推送一个失效时间戳),或者相反,推送一个携带未来时间戳的304来更新资源的生存期。简言之,服务器能够主动的管理客户端缓存!
如果服务器过于激进或者不守规则,那么客户端可以限制推送流的数量,或者只要它愿意它可以取消某一个流。找出合适的策略并在两端之间作出平衡,是找出服务器推送最佳实践的关键 - 这不是一项轻松的挑战,但却能带来很高回报。
注: 目前的浏览器不支持推送缓存再验证。应该支持吗?


服务器推送的客户端通知
HTTP 2.0服务器推送不是诸如Server-Sent Events(SSE)或WebSocket的技术替代品。通过HTTP 2.0服务器推送传递过来的资源由浏览器来处理,但却不能上升到程序代码的层面 - 因为没有JavaScript API来获取这些事件的通知。不过,解决这个难题的方法却很简单,因为我们可以把一个SSE通道和服务器推送结合起来,使两者都达到最佳效果:

spdy.createServer(options, function(req, res) {
  // set content type for SSE stream
  res.setHeader('Content-Type', 'text/event-stream');
  messageId = 1;
  setInterval(function(){
    // push a simple JSON message into client's cache
    var msg = JSON.stringify({'msg': messageId});
    var resourcePath = '/resource/'+messageId;
    res.push(resourcePath, {}, function(err, stream) { stream.end(msg) });
    // notify client that resource is available in cache
    res.write('data:'+resourcePath+'\n\n');
    messageId+=1;
  }, 2000);
}).listen(443);


诚然,下面这个例子有点儿傻,但却很能说明问题: 服务器每隔两秒钟产生一条消息,并把它推送到客户端的缓存里,然后发送一个SSE通知到客户端。另一方面,客户端在应用程序代码中订阅这些事件,并执行自己的逻辑来处理这些事件:     
            
  var source = new EventSource('/');
  source.onmessage = function(e) {
    document.body.innerHTML += "SSE notification: " + e.data + '
';
    // fetch resource via XHR... from cache!
    var xhr = new XMLHttpRequest();
    xhr.open('GET', e.data);
    xhr.onload = function() {
      document.body.innerHTML += "Message: " + this.response + '
';
    };
    xhr.send();
  };
            
长效的SSE流,被推送的资源,和其它所有HTTP 2.0流都有效的复用了同一个TCP链接 - 没有额外的链接开销和不必要的网络往返。通过把SSE和服务器推送结合起来,我们可以传送任意资源(二进制或文本)到客户端,利用浏览器本地缓存带来的好处,并执行恰当的应用逻辑! 最重要的是,今天这已经成为可能。


服务器推送创新
服务器推送开启了一个充满了优化机会的全新世界。我们上面所举的例子只是展示了冰山一角,仍有许多其他问题需要考虑:

            
  • 什么资源应当被推送? 何时被推送?它们是否已经在缓存中?
  • 服务器能够自动推断应当推送哪些资源吗?
  • 是否应当支持诸如主动缓存管理之类的高级应用?
  • 我们应当怎样设计我们的应用,才能从服务器推送中获益最多?
  • ...
通过HTTP 2.0,服务器有机会变得非常非常智能,包括如何优化传送一些具体的资源,更重要的是,也包括优化对整个应用的传送。类似的,浏览器可能增加额外的API和能力来使这个过程更加高效。事实上,长期来看,服务器推送很可能会成为HTTP 2.0的杀手级特性!

英文原文:Innovating with HTTP 2.0 Server Push

本文来自ChinaUnix新闻频道,如果查看原文请点:http://news.chinaunix.net/opensource/2013/0619/2814049.shtml

论坛徽章:
0
2 [报告]
发表于 2019-05-13 12:11 |只看该作者
之前有集成过一个第三方sdk,mobpush,他们那边有很多服务端sdk语言可以支持推送,用起来感觉还不错,推荐一下,有兴趣可以去了解!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP