前言
在现代 web 应用程序中,实时通信是当前非常重要的一部分,即时聊天、实时更新和实时操作等使用场景越来越多。传统的 HTTP 协议通信方式不支持持久连接,因此需要使用轮询等技术来模拟实时通信,但这种方式会消耗大量的带宽和服务器资源,产生不必要的延迟。WebSocket 诞生后,它使得创建实时应用程序变得更加容易。在这篇文章中,我们将深度分析 WebSocket 和 Socket.io 技术,展示它们的原理及实现及在前端中应用的喜人成果。
WebSocket
WebSocket 实现了一个真正的持久化的 TCP 连接,是基于标准的 TCP 协议的双向通信协议,可以在客户端和服务器之间单独建立连接。WebSocket 相比传统的 HTTP 协议通信方式,优点如下:
- 通过构造的套接字(web socket)进行浏览器和服务器之间 的双向通信。
- 传递二进制或者文本数据。
- 客户端和服务端可以自己随时发送消息到对方,而不需要经过浏览器http客户端发起的请求得到相应。
- 基于事件模型实现
- 减少需要传输的数据量,在传输层面上优化性能,降低服务端的负载压力和提升响应速度等。
- 客户端和服务器之间建立的连接是全双工的,可以在服务器任何时间发起数据推送。
使用 WebSocket,我们可以在客户端和服务器之间创建持久连接并交换数据,其通信过程如下图所示:
在前端中,创建 WebSocket 连接非常简单。以 JavaScript 为例,创建 WebSocket 连接的方式如下:
let ws = new WebSocket('wss://example.com');
WebSocket 提供了以下针对连接状态的事件:
onopen
: 连接建立时触发。onmessage
: 接收到服务器消息时触发。onerror
: 遇到错误时触发。onclose
: 连接关闭时触发。
-- -------------------- ---- ------- --------- - --------------- - ------------------------- -- ------------ - --------------- - ----------------------- ------------ -- ---------- - --------------- - ------------------------ -------- ------- -- ---------- - --------------- - ---------------------- ------- --
我们还可以通过 send
方法向服务器发送消息:
ws.send('Hello, server!');
上面的示例仅仅是演示 WebSocket API 的基本用法,它仅支持文本消息的发送,无法处理复杂的二进制数据类型。
Socket.io
Socket.io 是一个实现 WebSocket 协议的 JavaScript 库,它包含了一系列实用的特性,包括数据传输的可靠性、支持跨域访问等。主要特性如下:
- 统一双向通信 API:在 WebSocket API 上增加了事件订阅(Pub/Sub)模型,客户端和服务端可以通过 emit 和 on 来发射和监听任意事件。
- 多协议支持:支持 Websocket, HTTP 以及其它实时通信协议,无需担心在不同环境下兼容和兼容性。
- 自动尝试协议升级:在 WebSocket 不可用时,自动尝试使用其它兼容方式进行通信。
- 自适应轮询(Adaptive polling):自动判断当客户端在低速或不稳定网络环境时使用长轮询或短轮询进行交互。
- 连接失败时的兼容性:在浏览器或者 node.js 未开启 WebSocket 支持时,使用内置的 Flash 功能提供兼容。
使用 Socket.io 的方式如下:
首先,在服务器端安装 Socket.io:
npm i socket.io
在服务器端创建 Socket.io 针对 WebSocket 的实例:
const app = require('express')(); const http = require('http').createServer(app); const io = require('socket.io')(http); http.listen(3000, function() { console.log('listening on *:3000'); });
在客户端创建 Socket.io 连接:
let socket = io('http://localhost:3000');
之后,我们将发布具有名称“hello”的事件至服务器:
socket.emit('hello', 'World');
在服务器端监听来自客户端的“hello”事件:
io.on('connection', socket => { socket.on('hello', data => { console.log(data); // 'World' }); });
通过 Socket.io,我们可以在客户端和服务器之间实现双向通信,使得开发实时应用程序变得更加简单。
示例代码
-- -------------------- ---- ------- -- ----- --- ------ - ---------------------------- ------------------- --------------- -------------------- ---- -- - -- ---- ------------------ --- -- ------ ----- --- - --------------------- ----- ---- - ---------------------------------- ----- -- - --------------------------- ------------------- ------ -- - ----------------- ---- -- - ------------------ ----------- - ----- ----------------- ------ ---- ---------- ----------- ---------------- - ----- ---------- ----- ----- ------- --- --- -------------------- ---- -- - -------------------- -------- -- ---- ----------------- ---------------------------------- - ----- ---------- ----- ---- --- --- ----------------------- -- -- - ----------------- ---- ---- ----------------- ---------------------------------- - ----- ---------- ----- ----- ----- --- --- --- ----------------- -- -- - ---------------------- -- ------------------------ ---
上面的代码示例演示了如何使用 Socket.io 实现聊天室功能。客户端加入 chat-room-1 房间并监听来自服务器的 message 事件,同时向服务器发布 message 事件。服务器为每个连接接受的 Socket 对象保存了一个与其对应的房间名称,并根据客户端发送的消息将其广播给所有房间中的成员,实现了基本的聊天功能。
结论
WebSocket 和 Socket.io 实现了真正的实时通信,使得构建类似聊天室、在线游戏和实时交易等应用程序更加容易。在前端中,我们可以轻松使用 WebSocket 和 Socket.io 实现实时通信的功能,提升了应用程序的用户体验和反应速度。了解 WebSocket 和 Socket.io 的实现原理,可以使我们更好地使用这两个技术来构建更加高效的应用程序。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6747e6df5883fc5ebfe97911