当前Web应用中较常见的一种持续通讯方式,一般采起 setInterval 或者 setTimeout 实现。例如若是咱们想要定时获取并刷新页面上的数据,能够结合Ajax写出以下实现:
setInterval(function() {
$.get("/path/to/server", function(data, status) {
console.log(data);
});
}, 10000);复制代码
上面的程序会每隔10秒向服务器请求一次数据,并在数据到达后存储。这个实现方法一般能够知足简单的需求,然而同时也存在着很大的缺陷:在网络状况不稳定的状况下,服务器从接收请求、发送请求到客户端接收请求的总时间有可能超过10秒,而请求是以10秒间隔发送的,这样会致使接收的数据到达前后顺序与发送顺序不一致。因而出现了采用 setTimeout 的轮询方式:javascript
function poll() {
setTimeout(function() {
$.get("/path/to/server", function(data, status) {
console.log(data);
// 发起下一次请求
poll();
});
}, 10000);
}复制代码
程序首先设置10秒后发起请求,当数据返回后再隔10秒发起第二次请求,以此类推。这样的话虽然没法保证两次请求之间的时间间隔为固定值,可是能够保证到达数据的顺序。html
程序在每次请求时都会新建一个HTTP请求,然而并非每次都能返回所需的新数据。当同时发起的请求达到必定数目时,会对服务器形成较大负担。
客户端发送一个request后,服务器拿到这个链接,若是有消息,才返回response给客户端。没有消息,就一直不返回response。以后客户端再次发送request, 重复上次的动做。
http协议的特色是服务器不能主动联系客户端,只能由客户端发起。它的被动性预示了在完成双向通讯时须要不停的链接或链接一直打开,这就须要服务器快速的处理速度或高并发的能力,是很是消耗资源的。
websocket是HTML5的一个新协议,它容许服务端向客户端传递信息,实现浏览器和客户端双工通讯
由于 HTTP 协议有一个缺陷:通讯只能由客户端发起。 举例来讲,咱们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议作不到服务器主动向客户端推送信息。这种单向请求的特色,注定了若是服务器有连续的状态变化,客户端要获知就很是麻烦。咱们只能使用"轮询":每隔一段时候,就发出一个询问,轮询的效率低,很是浪费资源(由于必须不停链接,或者 HTTP 链接始终打开)。所以,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。
服务器能够主动向客户端推送信息,客户端也能够主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
跨平台的WebSocket通讯库,具备先后端一致的API,能够触发和响应自定义的事件。socket.io最核心的两个api就是emit 和 on了 ,服务端和客户端都有这两个api。经过 emit 和 on能够实现服务器与客户端之间的双向通讯。
var app = require('express')();
var http = require('http');
var socketio = require("socket.io");
const server = http.createServer(app)
const io = socketio(server)
var count = 0;
// WebSocket 链接服务器
io.on('connection', (socket)=> {
//// 全部的事件触发响应都写在这里
setInterval(()=>{
count++
//向创建该链接的客户端发送消息
socket.emit('mynameEv', { name:"你我贷"+count})
},1000)
//监听客户端发送信息
socket.on('yournameEv', function (data) {
console.log(data)
})
})
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
// 启用3000端口
server.listen(3000)复制代码
<body>
<div id="myname"></div>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var count = 0;
const socket = io.connect('http://localhost:3000')
socket.on('mynameEv', (data)=>{
document.getElementById("myname").innerHTML = data.name;
console.log(data.name)
setInterval(()=>{
count++
socket.emit('yournameEv', { name:"飞旋"+count})
},1000)
})
</script>
</body>复制代码