基于websocket与node搭建简易聊天室
一、前言
上一篇文章介绍了websocket的详细用法与工具类的封装,本篇就基于websocket搭建一个简易实时的聊天室。
在本篇开始之前也可以去回顾一下websocket详细用法:WebSocket详解与封装工具类

二、基于node搭建后台websocket服务
首先确认本机电脑中是否安装node,可以通过cmd打开命令窗口运行node -v查看node版本;
- 建议创建一个空项目:
npm init
- 一路回车就行,然后就得到了一个package.json的配置文件;安装
ws模块
npm i ws
- 新建app.js文件,源码如下:
const WebSocket = require('ws');
// 随机姓名
const names = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何','吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛','奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑','薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余','元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹'
];
// 获取随便昵称
const getRandom = (min, max) => {return Math.floor(Math.random() * (min - max) + max)
};
// 创建 WebSocket 服务器实例
const wss = new WebSocket.Server({port: 8080
});
// 监听连接事件
wss.on('connection', function(socket) {console.log('新连接');const randomIndex = getRandom(0, names.length - 1);socket.nickname = names.splice(randomIndex, 1)[0];sendMessageToClient( '连接成功!进入聊天室!');// 监听接收消息事件socket.on('message', function(message) {sendMessageToClient(message);});// 监听接收消息事件socket.on('close', function() {// 广播消息给所有客户端wss.clients.forEach(function each(client) {if (client.readyState === WebSocket.OPEN) {client.send(JSON.stringify({nickname: socket.nickname,msg: '退出聊天室!',}));}});});// 监听接收消息事件socket.on('error', function() {// 广播消息给所有客户端wss.clients.forEach(function each(client) {if (client.readyState === WebSocket.OPEN) {client.send(JSON.stringify({nickname: socket.nickname,msg: '网络不佳,连接失败 !',}));}});});// 发送消息到客户端function sendMessageToClient(message) {let targetMsg = message instanceof Buffer ? message.toString() : message;// 广播消息给所有客户端wss.clients.forEach(function each(client) {if (client.readyState === WebSocket.OPEN) {client.send(JSON.stringify({nickname: socket.nickname,msg: targetMsg,}));}});}
});
- 最后启动node服务:
node app.js;
三、前端构建聊天室
3.1 确定功能点
- 会话框中展示聊天内容;
- 输入框与发送按钮发送消息内容;
- 连接websocket,监听实时消息展示到界面中;
3.2 界面结构搭建

代码结构:
<div class="main_container"><!-- 消息框 --><div id="msgList"></div><!-- 发送消息 --><div class="controls"><input type="text" class="pushMsg" /><button id="btn">发送</button></div>
</div>
3.3 代码逻辑
-
引入之前封装的websocket工具类;
<script src="./utils/websocket.js"></script> -
实例化连接websocket;
const newWebSocket = new WebSocketClient('ws:localhost:8080'); newWebSocket.connect(); -
定义消息列表,监听返回消息信息,根据消息展示到界面中;
// 消息列表 const msgList = []; newWebSocket.addEventListener('message', handleMessage); // 处理返回数据 function handleMessage(msg) {const msgData = JSON.parse(msg.data || '{}');console.log(msgData, "返回数据====");if (msgData && typeof msgData.msg === 'string' && !msgData.msg.includes('ping')) {msgList.push({name: msgData.nickname,msg: msgData.msg,});const str = msgList.reduce((cur, next) => {let curMsg = '';if (next.msg.includes('连接')) {curMsg = `<div class="center_msg">玩家:${next.name}_${next.msg}</div>`;} else {curMsg = `<div class="msg_line"><div class="avatar">${next.name}</div><div class="msg_text">${next.msg}</div></div>`;}return cur += curMsg;}, '');$('#msgList').html(str);// 获取设置了滚动属性的div标签const div = document.getElementById('msgList');// 设置滚动的顶点坐标为滚动的总高度div.scrollTop = div.scrollHeight;} }newWebSocket.addEventListener('message', handleMessage); // 处理返回数据 function handleMessage(msg) {const msgData = JSON.parse(msg.data || '{}');console.log(msgData, "返回数据====");if (msgData && typeof msgData.msg === 'string' && !msgData.msg.includes('ping')) {msgList.push({name: msgData.nickname,msg: msgData.msg,});const str = msgList.reduce((cur, next) => {let curMsg = '';if (next.msg.includes('连接')) {curMsg = `<div class="center_msg">玩家:${next.name}_${next.msg}</div>`;} else {curMsg = `<div class="msg_line"><div class="avatar">${next.name}</div><div class="msg_text">${next.msg}</div></div>`;}return cur += curMsg;}, '');$('#msgList').html(str);// 获取设置了滚动属性的div标签const div = document.getElementById('msgList');// 设置滚动的顶点坐标为滚动的总高度div.scrollTop = div.scrollHeight;} } -
监听输入框回车事件,与发送按钮点击事件,发送消息;
// 监听发送按钮 $('#btn').on('click', sendMessage);// 输入框回车事件 $('.pushMsg').keydown(function(event) {if (event.key === 'Enter') {sendMessage();} }); // 发送消息 function sendMessage() {const msg = $('.pushMsg').val();if (msg) {newWebSocket.send(`${msg}`);$('.pushMsg').val('');} }
四、涉及小知识点
-
取消滚动条的展示,发送消息后默认展示最下方数据;
#msgList::-webkit-scrollbar {width: 0; }// 获取设置了滚动属性的div标签 const div = document.getElementById('msgList'); // 设置滚动的顶点坐标为滚动的总高度 div.scrollTop = div.scrollHeight; -
输入框监听keydown事件,当key为
Enter时发送消息(也可设置其他按键)// 输入框回车事件 $('.pushMsg').keydown(function(event) {if (event.key === 'Enter') {sendMessage();} }); -
取消input的光标进入的表框效果
outline: none; -
鼠标小手的出现
cursor: pointer;
五、聊天室完整前端源码
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>聊天通信</title><script src="./utils/jquery.min.js"></script><script src="./utils/websocket.js"></script><style>.main_container {width: 500px;margin: auto;}#msgList {width: 500px;height: 400px;overflow: auto;border: 2px solid #8491fe;border-radius: 10px;padding: 6px;background-color: #ebffff;box-sizing: border-box;}#msgList::-webkit-scrollbar {width: 0;}.msg_line {margin: 10px 0;display: flex;flex-wrap: wrap;}.avatar {width: 30px;height: 30px;border-radius: 50%;background-color: #77ffff;text-align: center;line-height: 30px;color: #333;font-size: 12px;margin-right: 6px;}.msg_text {display: inline-block;padding: 4px 12px;border-radius: 6px;background-color: #f0f1dd;font-size: 14px;}.center_msg {text-align: center;color: #f19597;}.controls {width: 100%;display: flex;justify-content: space-between;margin-top: 10px;}input {flex: 1;outline: none;height: 34px;line-height: 34px;border: 1px solid #d8d8d8;border-radius: 4px;padding: 0 4px;color: #333;margin-right: 12px;}#btn {width: 80px;height: 34px;cursor: pointer;}</style></head><body><div class="main_container"><!-- 消息框 --><div id="msgList"></div><!-- 发送消息 --><div class="controls"><input type="text" class="pushMsg" /><button id="btn">发送</button></div></div><script src="./utils/websocket.js"></script><script>// 消息列表const msgList = [];// 初始化websocketconst newWebSocket = new WebSocketClient('ws:localhost:8080');newWebSocket.connect();window.NewWebSocket = newWebSocket;newWebSocket.addEventListener('message', handleMessage);// 处理返回数据function handleMessage(msg) {const msgData = JSON.parse(msg.data || '{}');console.log(msgData, "返回数据====");if (msgData && typeof msgData.msg === 'string' && !msgData.msg.includes('ping')) {msgList.push({name: msgData.nickname,msg: msgData.msg,});const str = msgList.reduce((cur, next) => {let curMsg = '';if (next.msg.includes('连接')) {curMsg = `<div class="center_msg">玩家:${next.name}_${next.msg}</div>`;} else {curMsg = `<div class="msg_line"><div class="avatar">${next.name}</div><div class="msg_text">${next.msg}</div></div>`;}return cur += curMsg;}, '');$('#msgList').html(str);// 获取设置了滚动属性的div标签const div = document.getElementById('msgList');// 设置滚动的顶点坐标为滚动的总高度div.scrollTop = div.scrollHeight;}}// 监听发送按钮$('#btn').on('click', sendMessage);// 输入框回车事件$('.pushMsg').keydown(function(event) {if (event.key === 'Enter') {sendMessage();}});// 发送消息function sendMessage() {const msg = $('.pushMsg').val();if (msg) {newWebSocket.send(`${msg}`);$('.pushMsg').val('');}}</script></body>
</html>
相关文章:
基于websocket与node搭建简易聊天室
一、前言 上一篇文章介绍了websocket的详细用法与工具类的封装,本篇就基于websocket搭建一个简易实时的聊天室。 在本篇开始之前也可以去回顾一下websocket详细用法:WebSocket详解与封装工具类 二、基于node搭建后台websocket服务 首先确认本机电脑中…...
DevOps全面综述:从概念到实践
一、背景与概述 1.1 DevOps的起源与发展 DevOps(Development and Operations的缩写)是软件工程领域中的一种文化和实践方法,旨在促进开发团队与运维团队之间的协作,从而实现更高效、更可靠的软件交付。DevOps起源于敏捷软件开发方…...
[C++]vector的模拟实现
下面是简单的实现vector的功能,没有涉及使用内存池等复杂算法来提高效率。 一、vector的概述 (一)、抽象数据类型定义 容器:向量(vector)vector是表示大小可以变化的数组的序列容器。像数组一样…...
【云原生】Kubernetes----POD控制器
目录 引言 一、Pod控制器概述 二、Pod控制器的种类 (一)ReplicaSet (二)Deployment (三)StatefulSet (四)DaemonSet (五)Job 三、使用POD控制器 &a…...
Java环境配置(超详细)
Java环境配置(超详细) 引言1、安装 JDK1.1、下载安装JDK1.2、配置环境变量:JAVA_HOME1.3、将JAVA_HOME添加到Path中 2、安装 Maven2.1、下载安装Maven2.2、配置maven的环境变量: M2_HOME2.3、将Maven变量添加到Path中 引言 Java开发环境的配…...
【操作系统】(详细理解进程的状态)执行状态、就绪状态、阻塞状态、挂起状态
下面是进程的几种状态的概念: 执行状态:当一个进程已获得必要资源,并占有CPU进行执行。 就绪状体:进程已分配到除CPU外的所有必要资源,只要获取CPU允许就可立即执行。 阻塞状态:正在执行的进程,…...
C++ -- string常用接口的底层实现
一.string介绍 1. string是表示字符串的字符串类,对C语言的字符串指针进行了包装。 2. 该类的接口与常规容器的接口基本相同,有增删查改等,再添加了一些专门用来操作string的常规操作。 二.成员变量 创建string类的时候要在自己的命名空间…...
怎么做好企业短信服务呢?(文字短信XML接口示例)
企业短信服务已经成为各行各业都信赖的行业推广方式之一,并且短信行业也与时俱进的发展着,随之而来的就是市场上短信平台的数量也随之增多。那么怎么在鱼龙混杂的短信行业中选择适合自己的企业短信服务平台呢?企业短信服务平台又适用于哪些应…...
鸿蒙小案例-音乐播放器
之前参加鸿蒙比赛的音乐播放器 效果展示 HF音乐效果展示 功能列 有一些功能没写上去,自行发掘 说明: 1.API:网易云接口,QQ个人接口, 需要请看gitee 2.本地关系型数据由bug,提的工单已确认,建议使用API11,12,9的不稳…...
语言模型测试系列【9】
语言模型 文心一言讯飞星火通义千问2.5豆包360智脑百小应腾讯元宝KimiC知道 好长时间没有做语言模型的测试了,一方面是没有好的素材,各模型都在升级优化,而且频率很高;另一方面近期在阅读和学习其他的知识,所以更的也…...
优思学院|质量工程师工资不高怎么办?
你是否曾经好奇,为什么在职场中,质量工程师的工资普遍不高?这一现象背后的原因,实际上与他们的职业门槛和专业知识密切相关。早期,国内的质量工程师入行门槛较低,许多人即使没有任何专业知识也可以进入这一…...
【面向就业的Liux基础】从入门到熟练,探索Linux的秘密(一)
主要帮助大家面向工作过程中Linux系统常用的命令联系,采用极致的实用主义,帮助大家节省时间。 文章目录 前言 一、linux系统 二、linux系统基本命令 1.Linux系统的目录结构 2. 常用命令介绍 3.命令演示 4.作业练习 总结 前言 主要帮助大家面向工作过程中…...
高效数据处理的前沿:【C++】、【Redis】、【人工智能】与【大数据】的深度整合
目录 1.为什么选择 C 和 Redis? 2.人工智能与大数据的背景 1.大数据的挑战 2.人工智能的需求 3.C 与 Redis 的完美结合 1.安装 Redis 和 Redis C 客户端 2.连接 Redis 并进行数据操作 高级数据操作 列表操作 哈希操作 4.与大数据和人工智能结合 5.实际应…...
Vitis HLS 学习笔记--控制驱动与数据驱动混合编程
目录 1. 简介 2. 示例分析 2.1 代码分析 2.2 控制驱动TLP的关键特征 2.3 数据驱动TLP的关键特征 3. 总结 1. 简介 在 HLS 硬件加速领域,Vitis HLS 提供了强大的抽象并行编程模型。这些模型包括控制驱动和数据驱动的任务级并行性(TLP)&…...
VUE3 学习笔记(12):对比Vuex与Pinia状态管理的基本理解
在组件传值中,当嵌套关系越来越复杂的时候必然会将混乱,是否可以把一些值存在一个公共位置,无须传值直接调用呢?VUEX应运而生,但是从VUE3开始对VUEX的支持就不那么高了,官方推荐使用Pinia。 Vuex配置 ST1:…...
区间预测 | Matlab实现QRCNN-BiGRU-Attention分位数回归卷积双向门控循环单元注意力机制时序区间预测
区间预测 | Matlab实现QRCNN-BiGRU-Attention分位数回归卷积双向门控循环单元注意力机制时序区间预测 目录 区间预测 | Matlab实现QRCNN-BiGRU-Attention分位数回归卷积双向门控循环单元注意力机制时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实…...
TypeScript算法每日一题:赎金信(383)
作者:前端小王hs 阿里云社区博客专家/清华大学出版社签约作者✍/CSDN百万访问博主/B站千粉前端up主 题库:力扣 题目序号:383(简单) 题目:赎金信 给你两个字符串ransomNote 和 magazine,判断ran…...
springboot 作为客户端接收服务端的 tcp 长连接数据,并实现自定义结束符,解决 粘包 半包 问题
博主最近的项目对接了部分硬件设备,其中有的设备只支持tcp长连接方式传输数据,博主项目系统平台作为客户端发起tcp请求到设备,设备接收到请求后作为服务端保持连接并持续发送数据到系统平台。 1.依赖引入 连接使用了netty,如果项…...
kuka编程怎么加中文:解锁KUKA机器人编程中的中文支持
kuka编程怎么加中文:解锁KUKA机器人编程中的中文支持 在工业自动化领域,KUKA机器人以其卓越的性能和广泛的应用而备受赞誉。然而,对于许多中国用户来说,如何在KUKA编程中加入中文支持却成为了一个挑战。本文将从四个方面、五个方…...
hadoop集群中zookeeper的搭建与原理解释
搭建zookeeper 将zookeeper的apache-zookeeper-3.5.7-bin.tar.gz解压到/export/servers下 tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /export/servers为了方便后期使用解压后的文件夹改名为zookeeper-3.5.7 mv apache-zookeeper-3.5.7-bin zookeeper-3.5.7先进入zoo_…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
