设为首页 收藏本站
查看: 859|回复: 0

[经验分享] Websockets everywhere with Socket.IO

[复制链接]

尚未签到

发表于 2017-3-1 09:59:16 | 显示全部楼层 |阅读模式
  
最近一个小伙子过来吐槽,说ajax弱了,实现不了长链接,然后就一直哭....其实这未必不能实现,至于长链接,comet,server push都是依托与服务器的,如果服务器实现了server push那就好说了,据我了解现在的服务器大多都支持apache,jetty,fast cgi,ninix(重新加NGiNX_HTTP_Push_Module编译),但是这往往不够...好了,这样说不给力,下面我翻译了一篇Socket.IO.Js的文章里面较详细介绍了关于使用ajax保持http长连接的实现,以及Socket.IO的实现(就是兼容版实现Websockets ),同时涉及了Node.js(自己google)
  
http://howtonode.org/websockets-socketio
  
----转载请注明作者信息 ifree
  
正文:
  
如果你一直致力于实时网络应用,在过去几年你可能了解过一些不同的改善server端和client端数据交互延迟的技术.如果你正在开发一款多人游戏,一个及时聊天系统 或者一个想twitter一样需要频繁的与服务短交互的应用,你可能想'反转'传统的交互模型.所以,与其向服务端发送请求不如让服务端发送数据给你.
  
如今,当我们开发类似实时的系统是,我们总会想到长连接,comet当然还有websocket.但是,他们各有各的局限性,比如,服务器实现不同,限制太多,浏览器支持不够...
  
下面是我的Socket.IO的一段代码:

var socket = new io.Socket();
socket.on('connect', function(){
// connected!
});
socket.on('message', function(msg){
// message coming
});
socket.send('Hello world!');
  
如果你比较熟悉WebSocket(不熟悉去看api),其主要目的是简化HTTP的双向协议.你会发现它们非常类似.但是不同的是(由于目前浏览器尚未完全实现html5) Socket.IO支持 IE6-9, Firefox 3-4, Safari 3-5, Chrome 3-6, iOS (iPhone ,iPad)和其他兼容浏览器.


回顾当前的实时网络实现

  
在这个年代,一大部分web开发人员都在使用AJAX来实现实时交互(异步交互),就像Socket.IO一样.一些第三方js库比如jQuery,封装了兼容性较好的ajax对象来达到异步请求的功能.
  
比如说,如果你现在打算实时地向服务器请求资源,你可能会这样做:

setInterval(function(){
$.ajax({ url: '/my/page', success: function(data){
// do something with the data
} });
}, 5000);
  
这样,每五秒钟从服务器获取数据.在我看来,这几乎是和rfc1149(ip数据报)的规范一样高效.
  
你可能也会减少等待的时间:

setInterval(function(){
$.ajax({ url: '/my/page', success: function(data){
// do something with the data
} });
}, 100);
  
然而,你可能忽略了下面两个要点:



  • HTTP延迟.一个数据包在高速网络中往返可能消耗200ms,但是情况不总是这样,如果是500或更高,而且有时还不必要.因为:

  • 服务器可能没有我们要的数据,这样一来导致了很多不必要的带宽浪费.


长轮询

  
传统轮询的方法是不间断的向服务器请求数据,要克服它的缺点就要在服务器没有数据时保持长连接.这样也戏剧性的减少了网络延迟(长连接),所以,这也算一种服务器推送的技术.

function load(){
$.ajax({ url: '/my/page', success: function(){
// do something with the data
}, complete: load, timeout: 20000 });
}


如何做到长连接

  
如果你来自一个更传统的软件开发行业(比如桌面软件),你可能会想,我们为什么不保持长连接呢.
  
在浏览器上要实现可能有两种方法:



  • XMLHttpRequest 和 multipart/x-mixed-replace MIME 类型 (即在xhr请求中设置multipart为true的XMLHTTP实例);
  
虽然早在1995年Netsacpe就推出了这项技术(但不是对所有浏览器都有效),唯一在firefox浏览器下被普遍支持.



  • 使用 <iframe>时在头部meta信息设置 Transfer-encoding: chunked and Connection: keep-alive.
  
这样可以在创建<script>标签,动态执行脚本,iframe内部刷新而保持父窗口不刷新,这样也可以被看作是一种服务器推送的方法.
  
但这样做有一个缺点,就是浏览器下方出现无休止的进度条,严重的损害了用户体验.在ie环境下,可以把 <iframe> 放到一个隐藏的文档对象中(用ActiveX对象创建的htmlfile对象).在gmail 里面的gtalk实现给就是用的这个技术.是由Alex Russell 分析/发现的.
  
现在,很明显地看到这些技术在一定的环境下发挥了作用.但是最根本的是现在的服务器有着不同的请求的方法:



  • 请求头部信息(Content-Type, Connection...).

  • 持续连接(这需要长轮询的支持,但不是完全支持).

  • 框架信息.对于multipart,每条消息都要由'-----'分割符隔开解析麻烦(是的,每个请求的数据都被'----------'分割,请看请求数据).

  • 浏览器怪癖(比如ie在请求时需要一些空字节来识别每一条数据).
  
所有这些所做的都是尽可能减少数据的延迟,但是通常我们只把XMLHTTPRequest作为一个想服务端传输数据的良好解决方案.


通用的解决方案

  
有了WebSocket,"一个致力于解决bs架构的双端交互并且不依靠'multiple HTTP连接' ",像它的作者Hickson说的那样.
  
WebSocket 利用了HTTP/1.1规范的优势,可以说这是一个全新的协议:(有兴趣看rfc)

The Upgrade general-header allows the client to specify what additional communication protocols it supports and would like to use if the server finds it appropriate to switch protocols.
Examples: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
  
WebSocket在收发消息的时候并不关闭连接.除了本身的安全模型(基于utf-8编码的框架)以外,它可以完全被称作"web版的TCP".
  
但是WebSocket仍存在一些问题:



  • 服务器必须单独处理WebSocket请求,执行WebSocket特有的握手协议,WebSocket的协议.

  • 没有广泛的浏览器支持.


使用Node.js

  
Node.js 给开发人员带来了一个独特且令人兴奋的特性:你可以用当下最流行的脚本技术来编写你的无阻塞web服务器.
  
就像这样:

http.createServer(function (request, response) {
setTimeout(function(){
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}, 20000);
}).listen(8124);
  
虽然有了这个简单的api,但是你很难继续加强你的程序的逻辑.但是Socket.IO-node可以提供一个辅助的实现.下面是一个聊天程序差不多10行,同时支持服务器广播:

var buffer = [];
io.on('connection', function(client){
client.send({ buffer: buffer });
client.broadcast({ announcement: client.sessionId + ' connected' });
client.on('message', function(message){
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15) buffer.shift();
client.broadcast(msg);
});
client.on('disconnect', function(){
client.broadcast({ announcement: client.sessionId + ' disconnected' });
});
});
  
最好的是,在浏览里,它会处理你的长连接,flash socket,iframe请求.很棒把.


进一步阅读

  
如果你想进一步研究Socket.IO,你可以在git repositories检出源码进一步研究,也可以看一下几个项目(注:node.js是基于v8js引擎实现的高性能web服务器,很爽有时间去看吧):



  • http://github.com/substack/dnode

  • http://github.com/jacobthornton/space-tweet

  • http://github.com/mkilling/alfamegle

  • http://github.com/deserat/sock-drawer/

  • http://github.com/gerad/lazeroids-node/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348662-1-1.html 上篇帖子: Java的NIO以及线程并发 下篇帖子: 开源项目eRedG4_V1.03.1发布了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表