资讯动态

freeCodeCamp 实战教程:在 Advanced Node and Express 课程中用 Socket.IO 处理断线事件(Handle a Disconnect)

发布时间:2026/9/5 19:11:14 来源:尧图企业网站定制
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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价