0

0

如何在JavaScript中实现实时通信功能_WebSocket协议与Socket.io库实战【教程】

紅蓮之龍

紅蓮之龍

发布时间:2026-01-17 20:45:09

|

381人浏览过

|

来源于php中文网

原创

websocket是浏览器原生全双工协议,socket.io是其上层封装库;前者轻量低延迟但需手动处理连接与错误,后者支持自动降级、重连和房间管理,适合复杂业务场景。

如何在javascript中实现实时通信功能_websocket协议与socket.io库实战【教程】

WebSocket 是浏览器端唯一原生支持的全双工实时通信协议,Socket.io 则是在其基础上封装的兼容性更强、功能更丰富的库——但二者不是替代关系,而是分层协作:底层用 WebSocket 时最轻量、延迟最低;用 Socket.io 时能自动降级、自带重连和房间管理,适合业务复杂、客户端环境不可控的场景。

直接使用原生 WebSocket 连接服务端

适用于对延迟敏感、服务端已稳定支持 ws:// 协议、且不需要自动重连或广播等高级功能的场景。注意:WebSocket 构造函数只接受字符串 URL,不支持传入配置对象;连接状态需手动监听,错误无法自动恢复。

  • WebSocket 实例创建后立即触发连接,不能“暂停”或“配置后再连”
  • 必须监听 onopenonmessageonerroronclose 四个事件,缺一不可
  • 发送数据前必须确认 readyState === WebSocket.OPEN,否则会抛 SyntaxError: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state
  • 服务端地址必须是 ws://(开发)或 wss://(生产),http:// 会静默失败
const socket = new WebSocket('ws://localhost:3000');

socket.onopen = () => {
  console.log('Connected');
  socket.send(JSON.stringify({ type: 'join', room: 'chat-123' }));
};

socket.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
};

socket.onerror = (error) => {
  console.error('WebSocket error:', error);
};

socket.onclose = () => {
  console.log('Disconnected');
};

用 Socket.io 客户端连接并处理断线重连

Socket.io 默认启用自动重连,但默认参数在弱网下容易失效。关键点在于:重连逻辑由客户端控制,服务端无感知;重连期间未确认的消息会丢失,需业务层补发;reconnectionAttemptstimeout 必须显式设置才有效。

VIVA
VIVA

一个免费的AI创意视觉设计平台

下载
  • 不传选项时,io() 会尝试连接 /socket.io/ 路径,默认使用 polling + websocket 双传输
  • 强制只用 WebSocket:传入 { transports: ['websocket'] },但会失去 IE 等老浏览器兼容性
  • 重连失败后不会自动清空事件监听器,重复调用 io() 可能导致监听器叠加,建议复用实例
  • connect_error 事件比 error 更可靠,后者可能在握手阶段就触发,而前者确保连接尝试已完成
const socket = io('http://localhost:3000', {
  reconnection: true,
  reconnectionAttempts: 5,
  reconnectionDelay: 1000,
  timeout: 20000,
  transports: ['websocket', 'polling']
});

socket.on('connect', () => {
  console.log('Connected with id:', socket.id);
});

socket.on('connect_error', (err) => {
  console.error('Connection failed:', err.message);
});

socket.on('disconnect', (reason) => {
  console.log('Disconnected:', reason); // 'io server disconnect', 'transport close', etc.
});

区分 Socket.io 的 event emit 与 broadcast 行为

emit 是向目标 socket 发送消息,broadcast 是向“除自己外的所有同命名空间 socket”发送——但这个“所有”受作用域限制。常见误区是以为 broadcast 天然跨房间,其实它默认只在当前命名空间内广播,且不进房间(to(room) 才进)。

立即学习Java免费学习笔记(深入)”;

  • socket.emit('msg', data):仅自己收到
  • socket.broadcast.emit('msg', data):同命名空间内其他所有 socket 收到(不含自己)
  • io.to('room-1').emit('msg', data):指定房间内所有 socket(含自己)收到
  • socket.to('room-1').emit('msg', data):指定房间内其他成员(不含自己)收到
  • 房间名必须是字符串,不能是变量名或数字,否则 to() 无效且无报错
// 服务端示例(Node.js + socket.io)
socket.join('lobby');
socket.to('lobby').emit('user_joined', { id: socket.id });

// 客户端监听
socket.on('user_joined', (data) => {
  console.log('Someone joined lobby:', data.id);
});

真正难的是状态同步:WebSocket 没有内置消息确认机制,Socket.io 的 ack 回调只保证送达服务端,不保证业务逻辑执行成功。如果需要端到端可靠投递,得自己加序列号、重传和去重——这已经超出通信层范畴,属于应用协议设计了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

492

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

382

2023.10.25

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1566

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

649

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1184

2024.04.29

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号