发布时间:2026/9/5 19:11:11
freeCodeCamp 实战教程:在 Advanced Node and Express 课程中用 Socket.IO 处理断线事件(Handle a Disconnect) freeCodeCamp 实战教程在 Advanced Node and Express 课程中用 Socket.IO 处理断线事件Handle a Disconnect【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本篇基于 freeCodeCamp 开源仓库中advanced-node-and-express课程的 Handle a Disconnect 挑战文档讲解 Socket.IO 实时应用中一个最容易被忽视的细节客户端断开连接时服务端如何感知并同步在线用户数。读完本篇你将掌握socket.on(disconnect)的注册位置与监听层级、在线计数currentUsers的增减配对逻辑以及该项目测试断言如何校验你的实现。课程背景这一步在整个聊天项目中的位置Handle a Disconnect 是 advanced-node-and-express 挑战块 中的第 18 个挑战id589fc831f9fc0f352b528e76该块隶属于 Quality Assurance 认证见 quality-assurance 超块结构。整个挑战块后半段第 17–21 题共同构成一个逐步搭起来的实时聊天室项目Handle a Disconnect正处于承上启下的关键位置Set up the Environment用http.createServer(app)创建原生 HTTP 服务器通过require(socket.io)(http)挂载 Socket.IO并在服务端io.on(connection, socket { ... })中监听connection事件客户端则用let socket io();建立连接Communicate by Emitting定义let currentUsers 0;在每次新用户连接时currentUsers然后用io.emit(user count, currentUsers)把最新计数广播给所有客户端客户端用socket.on(user count, ...)接收Handle a Disconnect本文主题补上断开这一半让计数在用户离开时正确减一Authentication with Socket.IO用passport.socketio中间件解析 session cookie使socket.request.user可用从而知道是谁连接Announce New Users把 connect/disconnect 两个事件统一改名为user事件携带username、currentUsers、connected三个字段完成xx 已加入/离开聊天室的广播Send and Display Chat Messages完成聊天消息的收发与展示。核心概念disconnect 事件必须挂在 socket 上而不是 io 上原始文档589fc831f9fc0f352b528e76.md给出的核心论点是处理用户断开disconnect和处理初始连接connect一样简单区别在于 disconnect 必须监听在每一个 socket 上而不是整个 server 上。这正是 Socket.IO 事件模型的分层结构io.on(connection, socket { ... })服务器级事件。每当有新的客户端建立连接时触发一次回调参数socket代表这一个新连接的客户端。它回答的是谁来了socket.on(disconnect, ...)socket 级事件。Socket.IO 会在每个 socket 自身上发出disconnect事件回答的是这个特定的客户端走了。因为断开是某个具体连接的生命周期终点所以它的监听器只能注册在socket对象上。从文档给出的注册位置要求看这个监听器要写在现有的connect监听器内部——因为只有在connection回调的作用域里socket变量才可用io.on(connection, socket { // 连接时计数加一并广播上一步已实现 currentUsers; io.emit(user count, currentUsers); // 断开时在同一作用域内为这个 socket 注册 disconnect 监听 socket.on(disconnect, () { /*anything you want to do on disconnect*/ }); });文档还特别提醒disconnect不需要通过任何数据no data passed through传递。断开本身不携带业务负载服务端在回调里做日志、清理或计数即可。最简单的验证方式就是在回调里console.log一句某用户已断开然后在控制台观察效果。文档原文中的Note也点出了这个作用域规律就像disconnect一样socket 可以发出的所有其他事件都应该在有socket定义的那个 connection 监听器内部处理。完整实现断开时递减计数并广播只打印日志还不够。要让所有在线客户端持续看到准确的当前在线人数断开时必须做两件事把currentUsers减 1用更新后的计数再次 emituser count事件。结合前一步的代码服务端server.js中完整的 connect/disconnect 配对逻辑如下let currentUsers 0; io.on(connection, socket { // —— 连接计数 1 —— currentUsers; io.emit(user count, currentUsers); // —— 断开计数 -1 —— socket.on(disconnect, () { --currentUsers; io.emit(user count, currentUsers); }); });客户端client.js侧不需要任何改动——它在前一步已经注册了user count监听器socket.on(user count, function(data) { console.log(data); });于是形成闭环任何客户端接入或离开服务端都会把最新计数广播出去所有客户端的控制台或后续步骤中的界面都能实时刷新。测试断言分析项目如何校验你的实现该挑战属于 freeCodeCamp 的challengeType: 2带测试断言的实战项目题。从原始文档的# --hints--段落看共两条断言分别通过抓取你的/server.js与/public/client.js源码做正则匹配断言 1 —— 服务端必须处理 socket 的 disconnect 事件const url new URL(/_api/server.js, code); const res await fetch(url); const data await res.text(); assert.match(data, /socket.on.*(|)disconnect(|)/s, );正则/socket.on.*(|)disconnect(|)/s中的s标志允许.跨行匹配因此它验证的是存在socket.on且在其后允许跨多行出现以单引号或双引号包裹的disconnect事件名。这正对应文档强调的监听在 socket 上的要求——如果你错写成了io.on(disconnect, ...)这条断言就无法通过。断言 2 —— 客户端必须监听 user count 事件const url new URL(/public/client.js, code); const res await fetch(url); const data await res.text(); assert.match( data, /socket.on.*(|)user count(|)/s, Your client should be connection to server with the connection defined as socket );这条断言复用于本步骤与上一步它确保客户端用socket.on监听了user count保证断开后广播出去的计数确实有接收方。从源码结构看这些断言采用抓取用户代码文本 正则匹配的宽松策略只检查关键 API 调用形态而非运行时行为因此在通过断言之外仍建议按文档所说在浏览器多开几个标签页实际连入、断开用控制台日志验证计数增减是否符合预期。小结connect 与 disconnect 的对称设计把原始文档的操作要点归纳起来要点内容依据监听对象socket每个连接不是io服务器原始文档描述注册位置现有connect监听器内部socket作用域内原始文档描述事件负载disconnect不传递任何数据原始文档描述计数逻辑断开时--currentUsers原始文档描述广播事件更新后io.emit(user count, currentUsers)原始文档描述作用域规律socket 可发出的所有事件都应在 connection 回调内处理原始文档 Note这套connect 加一 / disconnect 减一的对称结构是后续 Announce New Users 一步的基础——那里会把这两个事件统一升级为携带username、currentUsers、connected三字段的user事件从而在聊天室里实时显示xx 已加入/离开。理解了本文的 socket 级事件注册位置与作用域规则后续步骤中的io.emit(user, {...})改造就可以水到渠成地完成。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

2026/9/5 19:11:11

Pixelle-Video 一句话生成 AI 短视频完整指南

Pixelle-Video 一句话生成 AI 短视频完整指南 【免费下载链接】Pixelle-Video 🚀 AI 全自动短视频引擎 | AI Fully Automated Short Video Engine 项目地址: https://gitcode.com/GitHub_Trending/pi/Pixelle-Video 在 Pixelle-Video 里输入一句"健康饮…

2026/9/5 19:06:11

开源中文字体霞鹜文楷:从下载到免费商用的完整指南

开源中文字体霞鹜文楷:从下载到免费商用的完整指南 【免费下载链接】LxgwWenKai An open-source Chinese font derived from Fontworks Klee One. 一款开源中文字体,基于 FONTWORKS 出品字体 Klee One 衍生。 项目地址: https://gitcode.com/GitHub_T…

2026/9/5 20:01:15

AI辅助开发A股量化工具:回测校验与实战防坑指南

前两天有人私信我,说想用AI直接给推几只明天能涨的股票。我回了一句:这个方向从起跑线就歪了。大模型并不适合用来猜行情,它真正擅长的是帮我把“量化工具”这种工程强度很高的东西快速落地。我自己最近就在用AI开发一个A股量化研究工具&…

2026/9/5 20:01:15

YOLOv8+Flask口罩检测系统实战:从数据集构建到Web部署

1. 系统架构与方案选型:为什么是 YOLOv8 Flask1.1 核心需求解析口罩检测这个课题在计算机毕业设计里属于经典中的经典,每年都有大量学生选它。原因很简单:数据集成熟、模型生态完善、应用场景好讲,而且"检测系统"比&qu…

2026/9/5 20:01:15

拆穿评论区“高维叙事”:五个认知偏差与五分钟验证法

这次不聊什么新框架,也不做环境部署。我们把目光放到一个每天都在出现的场景:评论区。总有一些评论看上去层级极高、逻辑自洽、甚至值得截图收藏,可只要你试图反驳,就会发现自己不知道从哪里下嘴。它把一件具体的小事,…

2026/9/5 2:46:54

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/5 2:46:52

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/5 2:44:34

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/5 0:04:47

流式背压机制:避免前端渲染卡死与内存暴涨的滑动窗口限流

流式背压机制:避免前端渲染卡死与内存暴涨的滑动窗口限流在大模型流式输出(Streaming)与智能体实时推流的架构中,生产环境中经常出现一种“上下游生产消费速率严重失衡”的极端情况: 生产端极速产出:大模型…

2026/9/5 2:45:13

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/5 2:30:42

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/5 2:46:50

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…