基于WebSocket的在线文字聊天室

news2024/12/24 2:58:12

与Ajax不同,WebSocket可以使服务端主动向客户发送响应,本案例就是基于WebSocket的一个在线聊天室,不过功能比较简单,只能满足文字交流。演示如下。

案例学习于b站up主,链接 。这位up主讲的非常清楚,值得去学习。本文属于记录自我学习过程的文章。

项目目录下app.js

//导入nodejs-websocket包
const { connect } = require('net')
const ws = require('nodejs-websocket')
const PORT = 3000

//创建一个server
const server = ws.createServer(connect => {
	console.log('有用户连接上来了')
})

server.listen(PORT,() => {
	console.log('websocket服务启动成功了,监听了端口'+PORT)
})

项目目录下打开终端 

npm install nodejs-websocket

 下载成功后。

 项目目录下index.html

 

去掉css。 

app.js 

//导入nodejs-websocket包
const { connect } = require('net')
const ws = require('nodejs-websocket')
const PORT = 3000

//连接的数量
let count = 0
//创建一个server
const server = ws.createServer(connect => {
	console.log('新的连接')
	count++
	connect.userName = `用户${count}`
	broadcast(`${connect.userName}进入了聊天室`)
	//接收
	connect.on('text',data => {
		broadcast(data)
	})
	//关闭
	connect.on('close',data => {
		console.log('关闭连接')
		count--
		broadcast(`${connect.userName}离开了聊天室`)
	})
	//异常
	connect.on('error',data => {
		console.log('发生异常')
	})
})

//广播
function broadcast(msg) {
	server.connections.forEach(item => {
		item.send(msg)
	})
}

server.listen(PORT,() => {
	console.log('websocket服务启动成功了,监听了端口'+PORT)
})

 index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			
		</style>
	</head>
	<body>
		<div></div>
		<input type="text" placeholder="请输入你的内容"/>
		<button>发送</button>
		<script>
			var input = document.querySelector('input')
			var button = document.querySelector('button')
			var div = document.querySelector('div')
			
			//websocket的服务地址
			var socket = new WebSocket('ws://localhost:3000')
			//连接成功时
			socket.addEventListener('open',function() {
				div.innerHTML = '连接服务成功了'
			})
			//主动向服务器发消息
			button.addEventListener('click',function() {
				var value = input.value
				socket.send(value)
			})
			//接受数据
			socket.addEventListener('message',function(e) {
				console.log(e.data)
				var dv = document.createElement('div')
				dv.innerText = e.data
				div.appendChild(dv)
			})
			//断开连接
			socket.addEventListener('close',function(e) {
				div.innerHTML = '服务断开连接'
			})
		</script>
	</body>
</html>

浏览框1

 

 浏览框2

 

稍微美化页面,增强一下逻辑。在浏览器内打开三个窗口,既有3个人参与到聊天室中,现在可以聊天了。

 用户1

用户2 

 用户3

 主要代码

请先安装node.js并已下载websocket的环境。

项目目录:

app.js

//导入nodejs-websocket包
const { connect } = require('net')
const ws = require('nodejs-websocket')
const PORT = 3000
const TYPE_ENTER = 0
const TYPE_LEAVE = 1
const TYPE_MSG = 2

//连接的数量
let count = 0
//创建一个server
const server = ws.createServer(connect => {
	console.log('新的连接')
	count++
	connect.userName = `用户${count}`
	broadcast({
		type: TYPE_ENTER,
		msg: `${connect.userName}进入了聊天室`,
		time: new Date().toLocaleString('chinese',{hour12:false}).slice(2).replace(/-/g,'/')
	})
	//接收
	connect.on('text',data => {
		broadcast({
			type: TYPE_MSG,
			msg: connect.userName + ':' + data,
			time: new Date().toLocaleString('chinese',{hour12:false}).slice(2).replace(/-/g,'/')
		})
	})
	//关闭
	connect.on('close',data => {
		console.log('关闭连接')
		count--
		broadcast({
			type: TYPE_LEAVE,
			msg: `${connect.userName}离开了聊天室`,
			time: new Date().toLocaleString('chinese',{hour12:false}).slice(2).replace(/-/g,'/')
		})
	})
	//异常
	connect.on('error',data => {
		console.log('发生异常')
	})
})

//广播
function broadcast(msg) {
	server.connections.forEach(item => {
		item.send(JSON.stringify(msg))
	})
}

server.listen(PORT,() => {
	console.log('websocket服务启动成功了,监听了端口'+PORT)
})

 index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			* {
				padding: 0;
				margin: 0;
			}
			body {
				background: #eff0fe;
				font-family: '宋体';
			}
			#box {
				padding: 20px;
			}
			input {
				width: 600px;
				height: 30px;
				border: none;
				outline: none;
				color: gray;
			}
			#chat {
				padding: 10px;
				background: white;
				width: 920px;
				box-sizing: border-box;
				height: 95vh;
			}
			#operation {
				position: fixed;
				top: 300px;
				right: 20px;
			}
			#title {
				font-size: 200px;
				position: fixed;
				top: 20px;
				right: 80px;
				color: gray;
				opacity: 0.3;
				font-family: '黑体';
			}
			button {
				height: 30px;
				width: 50px;
				text-align: center;
				line-height: 30px;
				border: none;
				color: gray;
			}
			button:hover {
				cursor: pointer;
			}
			.middle {
				width: 200px;
				margin: 0 auto;
				font-size: 3px;
				color: gray;
				margin-bottom: 5px;
			}
			.msg {
				width: 900px;
				word-break: break-all;
			}
			
		</style>
	</head>
	<body>
		<div id="box">
			<div id="chat"></div>
			<div id="title">聊天室</div>
			<div id="operation">
				<input type="text" placeholder="请输入你的内容"/>
				<button>发送</button>
			</div>
		</div>
		<script>
			const TYPE_ENTER = 0
			const TYPE_LEAVE = 1
			const TYPE_MSG = 2
			var input = document.querySelector('input')
			var button = document.querySelector('button')
			var div = document.querySelector('#chat')
			console.log(input)
			
			//websocket的服务地址
			var socket = new WebSocket('ws://localhost:3000')
			//连接成功时
			socket.addEventListener('open',function() {
				div.innerHTML = '欢迎来到聊天室'
			})
			//主动向服务器发消息
			button.addEventListener('click',function() {
				var value = input.value
				socket.send(value)
				input.value = ''
			})
			//接受数据
			socket.addEventListener('message',function(e) {
				console.log(e.data)
				var data = JSON.parse(e.data)
				if(data.type === TYPE_MSG) {
					var dv = document.createElement('div')
					var time = document.createElement('div')
					var msg = document.createElement('div')
					time.className = 'middle'
					msg.className = 'msg'
					time.innerText = data.time
					msg.innerText = data.msg
					dv.appendChild(time)
					dv.appendChild(msg)
				} else {
					var dv = document.createElement('div')
					var msg = document.createElement('div')
					var time = document.createElement('div')
					msg.className = 'middle'
					time.className = 'middle'
					msg.innerText = data.msg
					time.innerText = data.time
					dv.appendChild(time)
					dv.appendChild(msg)
				}
				div.appendChild(dv)
			})
			//断开连接
			socket.addEventListener('close',function(e) {
				div.innerHTML = '服务断开连接'
			})
		</script>
	</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/873992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【并发编程JUC】Future和CompletableFuture机制

场景题 面试的时候当面试官提出一个场景题&#xff0c;比如有一个翻译接口&#xff0c;同时调用百度、网易、谷歌的三个翻译接口&#xff0c;使用返回的第一个的翻译。这个时候一般的想法可能是&#xff0c;先串行执行。然后异步获取。但是其实都知道这样性能非常慢。 Future…

Baumer工业相机堡盟工业相机如何通过BGAPISDK设置相机的固定帧率(C#)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的固定帧率&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的固定帧率功能的技术背景CameraExplorer如何查看相机固定帧率功能在BGAPI SDK里通过函数设置相机固定帧率 Baumer工业相机通过BGAPI SDK设置相机固定帧…

【Linux系统编程】22.exec函数、execlp、execl、execvp

目录 exec函数 execlp 参数file 返回值 测试代码1 测试结果 execl 测试代码2 测试结果 execvp 测试代码3 测试结果 exec函数 fork创建子进程后执行的是和父进程相同的程序&#xff0c;但有可能执行不同的代码分支&#xff0c;子进程往往要调用一种exec函数以执行另…

如何在Vue2.X/Vue3.X项目引入jQuery,以及增加jQuery.easing扩展?让你的动画效果更加丝滑!

前言 还记得在2015左右&#xff0c;网页开发依然是jQuery的天下&#xff0c;虽然Vue、React开始盛行&#xff0c;以及后面Angular也开始抢占市场&#xff0c;但是jQuery在市场上依然占有较大的比重。当时的html页面大多是用jQuery来写的&#xff0c;为jQuery设计的插件也是相当…

应用层协议——TCP(上)

文章目录 1. TCP协议1.1 TCP协议段格式1.2 确认应答(ACK)机制1.3 16位窗口大小1.4 6位标志位1.4.1 TCP三次握手 1.5 确认应答(ACK)机制1.6 超时重传机制1.7 连接管理机制1.7.1 理解TIME_WAIT状态1.7.2 理解 CLOSE_WAIT 状态 1. TCP协议 TCP全称为传输控制协议&#xff0c;意思…

双端口存储器原理实验

1.实验目的及要求 1.1实验目的 1&#xff09;了解双端口静态随机存储器IDT7132的工作特性及使用方法。 2&#xff09;了解半导体存储器怎样存储和读出数据。 3&#xff09;了解双端口存储器怎样并行读写&#xff0c;并分析冲突产生的情况。 1.2实验要求 1&#xff09;做好…

百度屏蔽词有哪些?其中就有移民关键词指数被屏蔽?

我是百收网SEO&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 今日tombkeeper消息爆料&#xff1a;百度指数已经屏蔽“移民”等关键词指数。 大家好&#xff0c;我是百收网SEO商学院的狂潮微课老师&#xff0c;今天我们来讲解第 12 节课关键词优化难度分析…

JZ39数组中出现次数超过一半的数字

题目地址&#xff1a;数组中出现次数超过一半的数字_牛客题霸_牛客网 题目回顾&#xff1a; 解题思路&#xff1a; 最简单用哈希表来记录每个数字在数组中出现的次数&#xff0c;在遍历这个数组时同时进行判断是否满足条件。 整体代码&#xff1a; public int MoreThanHalfNum…

腾讯云服务器竞价实例是什么意思?CVM计费模式选择说明

腾讯云服务器CVM计费模式分为包年包月、按量计费和竞价实例&#xff0c;什么是竞价实例&#xff1f;竞价实例和按量付费相类似&#xff0c;优势是价格更划算&#xff0c;缺点是云服务器实例有被自动释放风险&#xff0c;腾讯云服务器网来详细说下什么是竞价实例&#xff1f;以及…

【MySQL】MySQL不走索引的情况分析

未建立索引 当数据表没有设计相关索引时&#xff0c;查询会扫描全表。 create table test_temp (test_id int auto_incrementprimary key,field_1 varchar(20) null,field_2 varchar(20) null,field_3 bigint null,create_date date null );expl…

C++多态与虚函数的原理与关系

C多态 多态可以分为编译时的多态和运行时的多态。前者主要是指 函数的重载&#xff08;包括运算符的重载&#xff09;、对重载函数的调用&#xff0c;在编译时就能根据实参确定应该调用哪个函数&#xff0c;因此叫编译时的多态&#xff1b;而后者则和继承、虚函数等概念有关。…

智慧交通项目实战全流程-DeepSort多目标跟踪车道线检测

1. 项目介绍 2. 算法库 2.1 numba介绍 numba是⼀个⽤于编译Python数组和数值计算函数的编译器&#xff0c;这个编译器能够⼤幅提⾼直接使⽤Python编写的函数的运算速度。 使用方法 numba对代码进⾏加速时&#xff0c;给要优化的函数加上jit优化器即可。使⽤jit的时候可以让…

IDEA断点调试(debug)

目录 1.断点调试介绍 2.F8逐行执行代码 3.调试遇异常 4.调试时如何看源码 5.如何直接执行到下一个断点 F9 6.利用断点调试查看动态绑定机制 1.断点调试介绍 断点调试是指在程序的某一行设置一个断点&#xff0c;调试时&#xff0c;程序运行到这一 行就会停住&#xff0…

2023年国赛数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 算法介绍FP树表示法构建FP树实现代码 建模资料 ## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c…

【Rust日报】2023-08-11 candle:一个极简的Rust机器学习框架

Bevys Third Birthday Bevy 是一个用 Rust 构建的令人耳目一新的数据驱动的游戏引擎&#xff0c;如果你想学习如何使用 Bevy 制作 2D/3D 游戏、可视化、用户界面或其他图形应用程序&#xff0c;那可以访问Bevy官网去了解更多。 阅读原文&#xff1a;https://bevyengine.org/new…

GPU Microarch 学习笔记 [1]

WARP GPU的线程从thread grid 到thread block&#xff0c;一个thread block在CUDA Core上执行时&#xff0c;会分成warp执行&#xff0c;warp的颗粒度是32个线程。比如一个thread block可能有1024个线程&#xff0c;分成32个warp执行。 上图的CTA&#xff08;cooperative thre…

西门子PLC模拟量接线及程序

接线 2线制接线 3线制接线 4线制接线 程序 指令 S_ITR 输入参数 EN 使能信号 AIW0 模拟量通道 ISH ISL 0-20ma对应 0-32000 4-20ma 对应 6400-32000 OSH OSL 传感器的测量值的最大和最小值 300 和 -50 输出参数 VD0 当前的测量温度

docker部署springboot

基础知识 什么是docker 官网&#xff1a; Docker Docs: How to build, share, and run applications | Docker Documentation Docker 是一个基于go语言开发的开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到…

Unity 鼠标实现对物体的移动、缩放、旋转

文章目录 1. 代码2. 测试场景 1. 代码 using UnityEngine;public class ObjectManipulation : MonoBehaviour {// 缩放比例限制public float MinScale 0.2f;public float MaxScale 3.0f;// 缩放速率private float scaleRate 1f;// 新尺寸private float newScale;// 射线pri…