采用nodejs + socket.io实现简易聊天室功能(群聊 + 私聊)
项目演示
支持群聊以及私聊

项目代码
index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="/socket.io/socket.io.js"></script><style>.box {display: flex;justify-content: space-between;width: 800px;margin: 50px auto;text-align: center;}.box>div {flex: 1;}.box .center {flex: 2;}.box .center input {width: 70%;}.list {list-style: none;text-align: left;}</style>
</head><body><div class="box"><div class="left"><div class="num">在线人数:1</div></div><div class="center"><h1 style="margin-bottom: 20px;">简易聊天室</h1><!-- 输入框 --><input type="text" class="ipt"><!-- 发送 --><button class="btn">发送消息</button><!-- 输入框 --><input type="text" class="joinNum"><!-- 加入房间 --><button class="joinBtn">加入房间</button><ul class="list" style="margin-top: 40px;"><!-- <li class="list-group-item">An item</li> --></ul></div><div class="right"><!-- <div>xxx已进入</div> --></div></div><script>let num = document.querySelector('.num')let ipt = document.querySelector('.ipt')let btn = document.querySelector('.btn')let joinNum = document.querySelector('.joinNum')let joinBtn = document.querySelector('.joinBtn')let list = document.querySelector('.list')let left = document.querySelector('.left')let center = document.querySelector('.center')let right = document.querySelector('.right')let socket = io()const name = prompt('请输入你的名称:')//把用户名称传递给服务端socket.emit('join', name)// 监听用户已进入 | 已退出socket.on('join', (obj) => {right.innerHTML += `<div>${obj.name} ${obj.status}</div>`})// 监听用户在线人数socket.on('userNum', (n) => {num.innerHTML = `在线人数:${n} 个人`})// 点击发送按钮 发送消息btn.addEventListener('click', function () {// 将数据传递给服务端socket.emit('value', ipt.value)})// 键盘按下回车 发送消息ipt.addEventListener('keydown', function (e) {if (e.key !== 'Enter') return// 将数据传递给服务端socket.emit('value', ipt.value)})// 加入房间joinBtn.addEventListener('click', function () {socket.emit("joinRoom", { room: joinNum.value, value: ipt.value })})// 服务端再把数据响应回来socket.on('value', (value) => {list.innerHTML += `<li>${value}</li>`ipt.value = ''})</script>
</body></html>
index.js
const app = require("express")();
const http = require("http").Server(app);
const io = require("socket.io")(http);app.get("/", (req, res) => {res.sendFile(__dirname + "/index.html");
});let userNum = 0; //当前在线人数io.on("connection", (socket) => {// 访问聊天室用户在线输了加1++userNum;// 将用户在线数量实时同步给客户端io.emit("userNum", userNum);// 相应客户端传递的数据socket.on("value", (value) => {io.emit("value", `${socket.username}:${value}`);});// 监听用户进入聊天室socket.on("join", (name) => {socket.username = name;io.emit("join", {name: name,status: "已进入",});});// 离开聊天室用户在线数量减1socket.on("disconnect", () => {--userNum;io.emit("userNum", userNum);io.emit("join", {name: socket.username,status: "已退出",});});// 加入房间socket.on("joinRoom", ({ room, value }) => {// 加入指定的房间socket.join(room);// 在指定房间中发送消息io.to(room).emit("value", `${socket.username}:${value}`);});
});http.listen(1231, () => {console.log("服务器已启动:http://localhost:1231");
});
package.json
{"name": "WebSocket","version": "1.0.0","main": "index.js","scripts": {"start": "node index.js"},"license": "MIT","dependencies": {"express": "^4.18.2","socket.io": "^4.5.4"}
}
通过 npm run start 运行项目
相关文章:
采用nodejs + socket.io实现简易聊天室功能(群聊 + 私聊)
项目演示 支持群聊以及私聊 项目代码 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport…...
消息队列(一):需求分析
为什么要做这样一个项目? 首先,我们在之前学习的时候,就认识了一下 生产者消费者模式,这样一个模式有两大好处: 解耦合 本来有个分布式系统,A服务器 调⽤ B服务器(A给B发请求,B给A…...
ImageViewer技术实现细节
第1章 ImageViewer工具使用方法 1.1. 图像加载 1.1.1. 单图像加载 左上角菜单,“File”->“单图像”,或者Ctrl-S,弹出文件对话框,选择图像文件,当前支持bmp,png,jpg格式。 结果如下图所示: 1.1.2. 多图像加载 左上角菜单,“File”->“多图像”,或者Ctrl-M…...
MFC多文档程序,从菜单关闭一个文档和直接点击右上角的x效果不同
MFC多文档程序,从菜单关闭一个文档和直接点击右上角的x效果不同 若文档内容有修改,则前者会询问用户,是否保存修改;后者不保存修改直接关闭。 原因在于,从菜单关闭时,调用OnClose,一定会调用Sa…...
【数据结构】C++实现AVL平衡树
文章目录 1.AVL树的概念2.AVL树的实现AVL树结点的定义AVL树的插入AVL树的旋转左单旋右单旋左右双旋右左双旋插入代码 AVL树的验证AVL树的查找AVL树的修改AVL树的删除AVL树的性能 AVL树的代码测试 1.AVL树的概念 二叉搜索树虽然可以提高我们查找数据的效率,但如果插…...
图神经网络系列之序章
文章目录 一、为什么需要图神经网络?二、图的定义1.图的定义和种类2.一些关于图的重要概念2.1 子图2.2 连通图2.3 顶点的度、入度和出度2.4 边的权和网2.5 稠密图、稀疏图 3.图的存储结构3.1 邻接矩阵3.2 邻接表3.3 边集数组3.4 邻接多重表3.5 十字链表3.6 链式前向…...
Unity中 UI Shader的基本功能
文章目录 前言一、实现思路1、暴露一个 2D 类型的属性来接受UI的纹理2、设置shader的层级为TransParent半透明渲染层级,一般UI都是在这个渲染层级3、更改混合模式,是 UI 使用的纹理,该透明的地方透明 二、代码实现 前言 Unity中 UI Shader的…...
【自学开发之旅】Flask-标准化返回-连接数据库-分表-orm-migrate-增删改查(三)
业务逻辑不能用http状态码判断,应该有自己的逻辑判断。想要前端需要判断(好多if…else),所以需要标准化,标准化返回。 json标准化返回: 最外面:data,message,code三个字段。 data:返回的数据 co…...
numpy增删改查
NumPy是一个用于科学计算的Python库,它提供了一个多维数组对象以及许多用于操作这些数组的函数。下面是关于如何在NumPy中进行增删改查操作的一些基本示例: 创建NumPy数组: import numpy as np # 创建一个一维数组 arr np.array([1, 2, 3, …...
【kafka】kafka重要的集群参数配置
如何规划Kafka 对于实际应用的生产环境中,需要尽量先规划设计好集群,避免后期业务上线后费力调整。在考量部署方案时需要通盘考虑,不能仅从单个维度上进行评估,下面是几个重要的维度的考量和建议: 这里重点说说操作系…...
cs224w_colab3_2023 And cs224w_colab4_2023学习笔记
class GNNStack(torch.nn.Module):def __init__(self, input_dim, hidden_dim, output_dim, args, embFalse):super(GNNStack, self).__init__() #这里的继承表示参见 https://blog.csdn.net/wanzew/article/details/106993425 # 继承时运行继承类别的函数 总之 __mro__的目的…...
Cannot find module ‘prop-types‘
把这个import删了。...
LeetCode-63-不同路径Ⅱ-动态规划
题目描述: 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。那…...
unity 使用Photon进行网络同步
Pun使用教程 第一步:请确保使用的 Unity 版本等于或高于 2017.4(不建议使用测试版)创建一个新项目。 第二步:打开资源商店并找到 PUN 2 资源并下载/安装它。 导入所有资源后,让 Unity 重新编译。 第三步…...
大数据课程M1——ELK的概述
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解ELK的定义; ⚪ 掌握ELK的使用; 一、什么是ELK 1. 简介 ELK 是elastic公司提供的一套完整的日志收集以及展示的解决方案,是三个…...
C# byte[] 如何转换成byte*
目标:将byte[]转成byte*以方便使用memcpy [DllImport("kernel32.dll", EntryPoint "RtlCopyMemory", CharSet CharSet.Ansi)] public extern static long CopyMemory(IntPtr dest, IntPtr source, int size); private void butTemp_Click(object…...
MySQL与Oracle的分页
MySQL与Oracle的分页 当我们通过SQL去查询一个结果集的时候,并不需要查看所有行,可能只是查看前几行,或者中间的几行。则需要像MySQL的limit或Oracle的ROWNUM与FETCH NEXT来实现。 MySQL 语法 SELECT * FROM table_name LIMIT [offset,] ro…...
git基本手册
Git and GitHub for Beginners Tutorial - YouTube Kevin Stratvert git config --global user.name “xxx” git config --global user.email xxxxx.com 设置默认分支 git config --global init.default branch main git config -h查看帮助 详细帮助 git help config 清除 cl…...
每日一题(两数相加)
每日一题(两数相加) 2. 两数相加 - 力扣(LeetCode) 思路 思路: 由于链表从头开始向后存储的是低权值位的数据,所以只需要两个指针p1和p2,分别从链表的头节点开始遍历。同时创建一个新的指针new…...
恒运资本:沪指震荡涨0.28%,医药板块强势拉升,金融等板块上扬
15日早盘,沪指盘中震荡上扬,科创50指数表现强势;北向资金小幅净流入。 到午间收盘,沪指涨0.28%报3135.31点,深成指、创业板指涨均0.11%,科创50指数涨1.04%;两市合计成交4357亿元,北…...
Windows 10/11下MySQL 8.0.28安装失败?‘服务没有响应控制功能’报错保姆级修复指南
Windows平台MySQL安装报错终极解决方案:从"服务无响应"到完美运行 遇到MySQL安装过程中弹出"服务没有响应控制功能"的红色报错窗口时,很多开发者第一反应是重装系统或更换数据库——别急!这个看似复杂的错误其实90%以上源…...
公交查询|智能公交|公交线路查询|基于SprinBoot+vue智能公交系统(源码+数据库+文档)
公交查询|智能公交|公交线路查询系统 目录 基于SprinBootvue智能公交系统 一、前言 二、系统设计 三、系统功能设计 1用户模块实现 2管理员服务端模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介…...
论文降AI率通关指南:7个实用技巧+高效工具一次讲清
为什么你的论文总被判定为AIGC疑似? 随着AI写作工具的广泛普及,不少科研人员和学生都碰到了同一个头疼的问题:论文AIGC疑似率超标。现在大多数高校都出台了明确规定,AIGC率超过30%就可能被判定为AI代写,直接取消答辩资…...
告别CubeMX代码洁癖:教你如何把main()函数挪到自己的.c文件里(STM32F4实战)
重构STM32工程的艺术:将main()迁移到自定义文件的实战指南 每次打开CubeMX生成的工程,看到那个被各种初始化代码塞满的main.c文件,你是否也感到一丝不适?作为一名有追求的嵌入式开发者,我们渴望对项目结构拥有绝对掌控…...
从零构建Telegram天气机器人:Python异步编程与API集成实战
1. 项目概述:一个能聊天的天气机器人 如果你用过Telegram,大概率会见过或者用过一些机器人。它们能帮你查新闻、翻译、管理任务,甚至陪你聊天。今天要聊的这个项目, imkarimkarim/Telegram-Weather-Bot ,就是一个典型…...
一站式解决Windows程序运行问题的Visual C++运行库修复指南
一站式解决Windows程序运行问题的Visual C运行库修复指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过打开软件时突然弹窗提示"缺少msv…...
管理幅度怎样设置才合理?
https://mp.weixin.qq.com/s/aoUgKUmsOUyC7wWOONMIIw...
大模型评测实战指南:从基准测试到技术选型的全流程解析
1. 项目概述:为什么我们需要一个“大模型评测”清单?如果你在过去一年里深度参与过大语言模型(LLM)的应用开发、技术选型或者仅仅是技术追踪,你大概率会和我有同样的感受:“评测”这件事,变得越…...
傅里叶变换加速视觉模型:频域卷积与FiT架构实战
1. 项目概述:用傅里叶变换为视觉模型“减负”在计算机视觉的模型炼金术里,我们总在追求一个看似矛盾的平衡:既要模型“看得更清”(更高的精度和更强的特征提取能力),又要它“跑得更快”(更低的计…...
从Softmax到ArcFace:PyTorch实战解析人脸识别中的角度间隔损失函数
1. 从Softmax到ArcFace:人脸识别损失函数的进化之路 人脸识别技术如今已经深入到我们生活的方方面面,从手机解锁到机场安检,背后都离不开一个关键环节——如何让模型学会区分不同的人脸。这就像教小朋友认人一样,我们需要告诉模型…...
