在前端实现数据通信时,我们通常会使用 socket.io 这个非常优秀的框架。但是在使用 socket.io 时,我们会面临一个选择:长轮询和 web socket。长轮询是传统的 Ajax 技术的一种升级,而 web socket 则是一种新的协议。
一、长轮询
长轮询是 Ajax 的一种升级,它的基本原理是客户端轮询,每隔一段时间向服务器发送一次请求,询问是否有新的数据可接收。服务器收到请求后,若有新的数据,则立即返回数据;如果没有,则等待一段时间后再返回。
长轮询的优缺点:
- 优点
- 兼容性好:长轮询可以被所有支持 JavaScript 的浏览器和服务器支持。
- 基于 HTTP:长轮询使用 HTTP 协议,因此比较容易开发和部署。
- 压力分散:长轮询可以帮助减少服务器的负担,因为长轮询会分散 HTTP 请求和响应的时间和数目。
- 缺点
- 延迟高:长轮询需要等待服务器返回数据,如果服务器没有数据可返回,则需要等待一段时间后再次请求。
- 浪费带宽:长轮询在等待服务器返回数据的时间段内,仍然会发出 HTTP 请求,占用带宽。
- 服务器压力大:长轮询会导致服务器上的连接数增加,对服务器造成较大的压力。
二、 web socket
web socket 是一种新的协议,它可以在客户端和服务器之间建立一个双向连接,实现实时数据交互。web socket 的基本原理是客户端和服务器通过握手建立连接,连接建立后可以随时进行数据交互,数据传输的过程中不需要经过 HTTP。
web socket 的优缺点:
- 优点
- 实时性好:web socket 可以实现服务器主动向客户端推送数据,实时性非常好。
- 带宽利用率高:web socket 只需要传送一次 HTTP 报文头,之后只需要通过数据帧传递数据,不需要反复的 HTTP 请求和响应,大大减少了带宽利用率。
- 服务器压力小:web socket 可以使用一个连接来维持数据交换,因此会占用服务器上的连接数更少,减少服务器的压力。
- 缺点
- 兼容性差:不是所有的浏览器都支持 web socket,一些老的浏览器不支持。
- 开发部署更加复杂:web socket 不同于 HTTP 协议,需要使用新的技术来实现。
- 安全性问题:web socket 建立的是一个持久连接,在传输过程中需要考虑数据安全性和防止恶意攻击等问题。
三、一些使用建议和示例代码
- 长轮询使用场景:长轮询可以用于在线状态、消息推送等不需要实时、数据量小的场景。以下是使用 socket.io 实现长轮询的示例代码:
// www.javascriptcn.com code example
// server.js
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs');
app.listen(3000);
function handler(req, res) {
// 省略
}
io.sockets.on('connection', function(socket) {
setInterval(function() {
socket.emit('server_data', {
data: '这是服务器的数据'
});
}, 2000);
});
// client.js
var socket = io.connect('http://localhost:3000');
socket.on('server_data', function(data) {
console.log(data.data);
});
- web socket 使用场景:web socket 可以用于实时聊天、在线游戏等需要实时、数据量大的场景。以下是使用 socket.io 实现 web socket 的示例代码:
// www.javascriptcn.com code example
// server.js
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs');
app.listen(3000);
function handler(req, res) {
// 省略
}
io.sockets.on('connection', function(socket) {
socket.on('client_data', function(data) {
socket.emit('server_data', {
data: '这是服务器的数据'
});
});
});
// client.js
var socket = io.connect('http://localhost:3000');
socket.on('server_data', function(data) {
console.log(data.data);
});
socket.emit('client_data', {
data: '这是客户端发来的数据'
});
在使用 socket.io 时,选择使用何种通信方式要根据实际需求来决定。如果数据量小且不需要及时响应,则可以使用长轮询;如果需要实时响应且数据量大,则应该使用 web socket。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d79804a941bf7134d96ead