在当今这个即时满足的时代,用户希望应用程序能够提供实时、动态的体验。我们希望立即看到社交媒体上朋友的更新,想知道何时有人回复了我们的聊天信息。
这就是 WebSockets 的用武之地。WebSockets 允许浏览器和服务器保持持久、低延迟的连接,从而实现即时、双向的信息流。与传统的 HTTP 请求-响应循环不同,WebSocket 协议通过单个 TCP 连接提供全双工通信。
利用 WebSockets,服务器可以向客户端推送数据,而无需客户端特别请求。这样,服务器就能自动向客户端发送实时更新,从而创建无缝的动态应用程序。在本文中,我们将介绍 WebSockets 的工作原理以及如何在 JavaScript 应用程序中实现 WebSockets。
什么是 WebSockets?
要了解 WebSockets,首先要了解传统的 HTTP 请求-响应模型是如何工作的。在 HTTP 中,客户端打开一个连接,发出请求,收到响应,然后关闭连接。这个循环根据需要反复进行。
这种方法的问题在于,每次请求/响应都要重复建立新连接,开销很大。此外,所有通信都是由客户端发起的。在客户端明确要求之前,服务器无法推送新数据。
WebSockets 允许客户端和服务器建立持久连接,任何一方都可以随时使用该连接开始发送数据,从而解决了这些问题。初次握手后,WebSocket 连接一直保持打开状态,直到客户端或服务器决定关闭为止,从而允许通过单个 TCP 套接字连接进行双向通信。
WebSockets 的主要优势
与 HTTP 相比,WebSockets 有几大优势:
更低的延迟: 无需重复打开/关闭连接。与 REST API 调用相比,WebSockets 的开销更少。
实时更新: 服务器可推送更新,而无需等待客户端请求。非常适合实时馈送和通知。
节省服务器资源: 单个打开的 WebSocket 连接比重复打开 HTTP 连接更有效。
支持新型应用程序:WebSockets 对于聊天、多人游戏和实时监控仪表板等需要持续通信的应用程序来说至关重要。
有了所有这些优势,难怪许多现代网络和移动应用程序都转向使用 WebSockets 来提供更动态、更实时的用户体验。
利用 WebSocket API 在 JavaScript 中使用 WebSockets
好消息是,WebSockets 已直接嵌入到现代网络浏览器中。通过 WebSocket API,我们可以在 JavaScript 中轻松使用 WebSockets:
// Create WebSocket connection
const socket = new WebSocket('ws://localhost:8080');
// Listen for when connection opens
socket.addEventListener('open', () => {
console.log('WebSocket Connected!');
});
// Listen for messages
socket.addEventListener('message', (event) => {
console.log('Message from server: ', event.data);
});
在这里,我们通过向 WebSocket 构造函数传递服务器端点 URL 来创建一个新的 WebSocket 实例。这会返回一个 WebSocket 对象,我们可以通过它发送和接收数据。
接下来,我们为连接成功打开和从服务器接收信息添加事件监听器。WebSocket 保持打开状态,允许我们无限量地交换数据,直到关闭为止。
向服务器发送数据
除了使用 .onmessage 监听器接收服务器数据外,我们还可以使用 .send() 向服务器发送数据:
socket.send('Hello Server!');
然后,服务器就可以监听信息并做出相应的响应:
// Server-side
websocket.on('message', (data) => {
websocket.send('Hello Client!');
});
建立在 WebSocket 协议之上的客户端 WebSocket API 使我们能够构建实时、双向应用程序,而无需担心底层 TCP/IP 连接和 HTTP 标头。
关闭 WebSocket
完成 WebSocket 连接后,我们可以从客户端或服务器端关闭它:
// Client-side
socket.close();
// Server-side
websocket.close();
close 方法允许传递整数状态代码和短字符串消息来描述连接关闭的原因。
WebSocket 的实际应用
既然了解了基础知识,让我们来看一个简单的示例应用程序,看看 WebSockets 的实际应用。我们将构建一个使用 WebSockets 进行实时消息传递的基本聊天应用程序。
从客户端的角度来看,它是如何工作的:
- 用户输入用户名
- 应用程序与服务器建立 WebSocket 连接
- 用户在输入框中输入聊天消息
- 消息通过 WebSocket 发送到服务器
- 应用程序显示从服务器收到的所有消息
下面是简化版的服务器逻辑:
- 维护当前连接的 WebSocket 客户端列表
- 接收来自客户端的新聊天消息
- 通过 WebSockets 向所有已连接的客户端发送消息
- 这样就可以向所有聊天参与者实时广播消息,而无需轮询服务器进行更新。
以下是基本实现的 JavaScript 代码:
// Client-side
const socket = new WebSocket('ws://chat.myapi.com/socket');
// Listen for connection open
socket.onopen = () => {
// Send join message to server
socket.send(JSON.stringify({
type: 'join',
username: 'Bob123'
}));
}
// Listen for messages
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
switch(data.type) {
case 'chat':
showNewMessage(data.username, data.message);
break;
}
}
// Send chat message
function sendChat(message) {
socket.send(JSON.stringify({
type: 'chat',
message
}));
}
// Server-side
const connectedUsers = [];
// Handle new WebSocket connection
function handleConnection(socket) {
socket.on('message', (data) => {
const {type, username, message} = JSON.parse(data);
switch(type) {
case 'join':
onUserJoin(connectedUsers, username);
break;
case 'chat':
onChatMessage(username, message);
break;
}
});
}
function onChatMessage(sender, message) {
connectedUsers.forEach(user => {
user.socket.send(JSON.stringify({
type: 'chat',
username: sender,
message
}));
});
}
function onUserJoin(userList, username) {
const user = {username, socket};
userList.push(user);
sendMessageToAll({
type: 'system',
message: `${username} joined chat`
});
}
虽然这只是最基本的,但它展示了我们如何使用 WebSockets 构建一个应用程序,向所有连接的客户端即时广播聊天信息。
下一级 Socket.IO
本机 WebSockets 提供底层基础架构,还有一些有用的 JavaScript 库(如 Socket.IO)可以封装 WebSockets 并提供自动重连、房间/命名空间和确认等额外功能。
不过,WebSockets 是使浏览器中的实时应用程序成为可能的核心通信协议。了解 WebSockets 如何提供双向、持久的通信通道是构建需要低延迟同步的现代应用程序的关键。
使用 WebSockets 增强应用程序
通过以上介绍,您可以了解 WebSockets 如何为更具交互性和动态性的应用程序打开大门。如果您正在开发需要实时数据流、消息传递或同步的应用程序,请考虑使用 WebSockets。
从 WebSockets 中受益匪浅的一些应用程序示例:
- 聊天/消息应用程序
- 实时仪表盘和图表
- 多人浏览器游戏
- 协作文档编辑
- 交易/博彩平台
- 实时体育更新
- 推送通知
- 远程系统监控
- 物联网设备控制
目前,WebSockets 已在所有主流浏览器(包括桌面浏览器和移动浏览器)中获得原生支持,应该成为每个现代Web开发人员工具包中的标准工具。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/im/44454.html