轮询、长轮询comet、长连接SSE、websocket

轮询、长轮询comet、长连接SSE、websocket

参考自:https://blog.csdn.net/xixingzhe2/article/details/112259874

Web端即时通讯技术:服务器端可以即时地将数据的更新或变化反应到客户端,例如消息即时推送等功能都是通过这种技术实现的。但一般的Web通信都是浏览器先发送请求到服务器,服务器再进行响应完成数据的现实更新。

实现Web端即时通讯的方法:实现即时通讯主要有四种方式,它们分别是轮询、长轮询(comet)、长连接(SSE)、WebSocket。
它们大体可以分为两类,一种是在HTTP基础上实现的,包括短轮询、comet和SSE;另一种不是在HTTP基础上实现是,即WebSocket。

1、轮询

优点是比较简单,易于理解,实现起来也没有什么技术难点。
缺点是显而易见的,这种方式由于需要不断的建立http连接,严重浪费了服务器端和客户端的资源。尤其是在客户端,如果有数量级想对比较大的人同时位于基于短轮询的应用中,那么每一个用户的客户端都会疯狂的向服务器端发送http请求,而且不会间断。人数越多,服务器端压力越大,这是很不合理的。

因此短轮询不适用于那些同时在线用户数量比较大,并且很注重性能的Web应用。

var xhr = new XMLHttpRequest();
setInterval(function(){
    xhr.open('GET','/user');
    xhr.onreadystatechange = function(){

    };
    xhr.send();
},1000)

2、长轮询(comet)

ajax实现:当服务器收到客户端发来的请求后,服务器端不会直接进行响应,而是先将这个请求挂起,然后判断服务器端数据是否有更新。如果有更新,则进行响应,如果一直没有数据,则到达一定的时间限制(服务器端设置)才返回。 客户端JavaScript响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。

长轮询和短轮询比起来,明显减少了很多不必要的http请求次数,相比之下节约了资源。长轮询的缺点在于,连接挂起也会导致资源的浪费。

 function ajax(){
     var xhr = new XMLHttpRequest();
     xhr.open('GET','/user');
     xhr.onreadystatechange = function(){
         ajax();
     };
     xhr.send();
 }

轮询与长轮询都是基于HTTP的,两者本身存在着缺陷:轮询需要更快的处理速度;长轮询则更要求处理并发的能力;两者都是“被动型服务器”的体现:服务器不会主动推送信息,而是在客户端发送ajax请求后进行返回的响应。而理想的模型是"在服务器端数据有了变化后,可以主动推送给客户端",这种"主动型"服务器是解决这类问题的很好的方案。WebSockets就是这样的方案。

3、长连接(SSE)

SSE是HTML5新增的功能,全称为Server-Sent Events。它可以允许服务推送数据到客户端。SSE在本质上就与之前的长轮询、短轮询不同,虽然都是基于http协议的,但是轮询需要客户端先发送请求。而SSE最大的特点就是不需要客户端发送请求,可以实现只要服务器端数据有更新,就可以马上发送到客户端。

SSE的优势很明显,它不需要建立或保持大量的客户端发往服务器端的请求,节约了很多资源,提升应用性能。并且后面会介绍道,SSE的实现非常简单,并且不需要依赖其他插件。

4、WebSocket

WebSocket是Html5定义的一个新协议,与传统的http协议不同,该协议可以实现服务器与客户端之间全双工通信。简单来说,首先需要在客户端和服务器端建立起一个连接,这部分需要http。连接一旦建立,客户端和服务器端就处于平等的地位,可以相互发送数据,不存在请求和响应的区别。

WebSocket的优点是实现了双向通信,缺点是服务器端的逻辑非常复杂。现在针对不同的后台语言有不同的插件可以使用。

websocket是一种全新的协议,不属于http无状态协议,协议名为"ws"

websocket与http关系:

http,请求和响应;websocket,广播和收听

相同点:

  1. 都是基于tcp的,都是可靠性传输协议
  2. 都是应用层协议

不同点:

  1. WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息
  2. HTTP是单向的
  3. WebSocket是需要浏览器和服务器握手进行建立连接的
  4. 而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接
socket.io

Socket.IO 是一个封装了 Websocket、基于 Node 的 JavaScript 框架,包含 client 的 JavaScript 和 server 的 Node。其屏蔽了所有底层细节,让顶层调用非常简单。
另外,Socket.IO 还有一个非常重要的好处。其不仅支持 WebSocket,还支持许多种轮询机制以及其他实时通信方式,并封装了通用的接口。这些方式包含 Adobe Flash Socket、Ajax 长轮询、Ajax multipart streaming 、持久 Iframe、JSONP 轮询等。换句话说,当 Socket.IO 检测到当前环境不支持 WebSocket 时,能够自动地选择最佳的方式来实现网络的实时通信。

// 客户端
// 先new一个对象,这里有两种:ws 和 wss,区别是wss被加密了,后面跟一个服务器地址,相当于类似一个对象来管理这个链接
// 需要做的有三个事件:onopen、onmessage、onclose、onerror

const ws = new WebSocket('ws://localhost:5000');

// 连接成功后
ws.onopen = function (evt) {
    console.log('Connection open ...');
    // 发送消息出去
    ws.send('Hello WebSockets!');
};

// onmessage事件,客户端和服务器互相发送和接收消息
ws.onmessage = function (evt) {
    ws.send('消息111')
    console.log('Received Message: ' + evt.data); // 后端返回的消息,data是信息的内容
    // 关闭通道
    ws.close(); // 客户端向服务器发送消息后要关闭,不关闭的话会一直发送"消息111",服务器也会一直接收到
};

// 最后你说你不用了,我这个连接的通道断了,你就监听onclose来确定它是不是关闭了,关闭的方法就是close()
ws.onclose = function (evt) {
    console.log('Connection closed.');
};


// 服务器
const Websocket = require('ws')

const wsServer = new Websocket.Server({port: 5000})

// 连接
wsServer.on('connection', (ws) => {
    // 发送和接收消息
    ws.on('message', (message) => {
        // message是客户端发送过来的消息
        console.log(message.toString()) // 这里message是一个Buffer对象,转为字符串形式
        if (message == 'nice to meet you') {
            ws.send("nice to meet you, too") 
        } else {
            ws.send('hahah')
        }
    })
})

比较

性能、兼容性对比

从兼容性角度考虑,短轮询>长轮询>长连接SSE>WebSocket;

从性能方面考虑,WebSocket>长连接SSE>长轮询>短轮询。

短轮询长轮询Websocketsse
通讯方式httphttp基于TCP长连接通讯http
触发方式轮询轮询事件事件
优点兼容性好容错性强,实现简单全双工通讯协议,性能开销小、安全性高,有一定可扩展性实现简便,开发成本低
缺点安全性差,占较多的内存资源与请求数安全性差,占较多的内存资源与请求数传输数据需要进行二次解析,增加开发成本及难度只适用高级浏览器
适用范围b/s服务b/s服务网络游戏、银行交互和支付服务端到客户端单向推送
延迟非实时,延迟取决于请求间隔非实时,延迟取决于请求间隔实时非实时,默认3秒延迟,延迟可自定义
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值