socket简易聊天系统

赵星华
2023-12-01
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>简易聊天室</title>
		<script src="http://localhost:5050/socket.io/socket.io.js"></script>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<style>
			#logpage{
				width: 100%;
				height: 100vh;
				display: flex;
				align-items: center;
				justify-content: center;
			}
			#chatpage{
				display: none;
				flex-direction: column;
				height: 100vh;
			}
			.header{ background-color: #222; height: 44px; line-height: 44px; display: flex; justify-content: space-between; padding: 0 15px; color:#fff}
			.header h1{font-size: 17px; margin: 0;}
			a{color:#aaa;text-decoration: none;}
			#online {   color: #777; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;}
			.tip{ 
				position: fixed; 
				left:50%; 
				top:50%;
				transform: translate(-50%,-50%);
				background-color: rgba(0,0,0,.4);
				border-radius: 6px;
				color:#fff;
				display: none;
				padding: 5px 15px;
				}
		.chatbox{ flex:1; background-color: #efefef;}
		.msgbox{ height: 160px; display: flex;}
		.msgbox button{  width: 120px;}
		.msgbox textarea { flex:1;background-color: #f0f0f0;}
		.msg{ margin: 15px; clear: both; display: flex; flex-direction: row-reverse; justify-content: flex-end;}
		.msg .uname{ 
			height: 60px; 
			line-height: 60px;
			width: 60px;
			overflow: hidden;
			white-space: normal;
			text-overflow: ellipsis;
			} 
		.msg .content{
			padding: 15px;
			border-radius: 4px;
			background-color: #fff;		    
			position: relative;
			max-width: 70%;
			
		}
		.msg .content::before{
			content: '';
			position: absolute;
			width: 0;
			height: 0;
			border:10px solid transparent;
			border-right-color:#fff;
			left:-20px;
			top:4px;
		}
		.msg.me{ flex-direction: row !important; justify-content: flex-end;}
		.msg.me .uname{text-align: right;}
		.me .content{ background-color: #1E90FF; color: #fff; text-align: right;}
		.msg.me .content::before{
			left:inherit;
			right:-20px;
			border-right-color:transparent;
			border-left-color:#1E90FF;
		}
		
		</style>
	</head>
	<body>
		<div id="logpage">
			<input type="text" id="username"> <button onclick="login()">登录</button>
		</div>
		<!-- 登录页面 -->
		<div id="chatpage">
			<div class="header"><h1>聊天室</h1> <span><span id="user"></span> <a href="javascript:location.reload()">退出</a></span></div>
			<p id="online"></p>
			<div class="chatbox"></div>
			<div class="msgbox">
				<textarea></textarea>
				<button onclick="sendMsg()">发送</button>
			</div>
		
		</div>
			<div class="tip"></div>
		<!-- 聊天页面 -->
		<script>
			var userid = new Date().getTime();
			 this.socket = io.connect("ws://localhost:5050"); // 连接socket服务器
			 var  username = null;
			 /**
			  * 登录
			  * */
			function login(){
				 username = document.getElementById("username").value; //获取user文本框的值
				if(!username){alert("用户名不能为空");return} // 判断如果为空则返回
				this.socket.emit("login",{userid:userid,username})//实现soket登录
				logpage.style.display = "none";//隐藏登录页面
				chatpage.style.display = "flex";// 显示聊天页面
				user.innerHTML = username;
			}
			function sendMsg(){
				var textarea = document.querySelector(".msgbox textarea"); //获取到textarea
				var message = textarea.value; // 获取用户输入的值
				this.socket.emit("message",{message,userid,username}); //发送信息
				textarea.value = ""; //请空输入框的值
				
			}
			 
			 
			
			 // 发送登录信息给服务器
			 this.socket.on("login",data=>{
				 
				 var str = []; //定义用户列表数组
				 for(key in data.onlineUsers){
					 str.push(data.onlineUsers[key])
				 }
				 // 遍历用户信息 存储到数组
				 str = str.join(", ");
				 // 转换为字符串
				 
				 online.innerHTML = `${data.onlineCount}人在线 ,${str}`;
				 // 用户登录提示
				 var tip = document.querySelector(".tip"); // 获取到提示dom 
				 tip.innerHTML = data.user.username +'进入聊天室'; //设置提示的文本
				 tip.style.display="block"; //显示提示
				 setTimeout(()=>{
					 tip.style.display = 'none' //1.5s 隐藏提示
				 },1500)
			 })
			 // 监听登录
			 
			 
			 
			 this.socket.on("message",data=>{			 
				var div = document.createElement("div"); //创建div
				console.log(data.userid,userid);
				var cname = data.userid == userid?'msg me':'msg'; //动作设置class
				div.className=cname; //添加class
				div.innerHTML = `<div class="content">${data.message}</div><div class="uname">${data.username}</div>`;
				//设置内容
				var chatbox = document.querySelector(".chatbox");
				// 选择到chatbox
				chatbox.appendChild(div);
				// 插入到页面中
			 })
			 // 监听 message事件 触发回调
			 
			 this.socket.on("logout",data=>{
				 var str = [];
				 for(key in data.onlineUsers){
				 					 str.push(data.onlineUsers[key])
				 }
				 str = str.join(", ");
				 
				 online.innerHTML = `${data.onlineCount}人在线 ,${str}`;
				 var tip = document.querySelector(".top")
				 tip.innerHTML = data.user.username +'离开聊天室'; //提示用户离开
				 tip.style.display="block";
				 setTimeout(()=>{
				 					 tip.style.display = 'none'
				 },1500)
			 })
			 // 监听 logout 注销事件 触发回调
		</script>
	</body>
</html>

后台代码

var app = require('express')();
//  创建一个app
var express = require('express');
// 需要express 
var http = require('http').Server(app);
// 需要http服务 
var io = require('socket.io')(http);
// 需要scocket

app.get('/', function(req, res){
	res.send('<h1>Welcome Realtime Server</h1>');
});
// app.use('/public', express.static(__dirname + 'public'));
app.use(express.static('public'))
//  设置静态文件夹
//在线用户
var onlineUsers = {};
//当前在线人数
var onlineCount = 0;
// 当用前端用户连接
io.on('connection', function(socket){
	console.log('a user connected');
	//监听新用户加入
	socket.on('login', function(obj){
		//将新加入用户的唯一标识当作socket的名称,后面退出的时候会用到
		socket.name = obj.userid;
		
		//检查在线列表,如果不在里面就加入
		if(!onlineUsers.hasOwnProperty(obj.userid)) {
			onlineUsers[obj.userid] = obj.username;
			//在线人数+1
			onlineCount++;
		}
		//向所有客户端广播用户加入
		io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
		console.log(obj.username+'加入了聊天室');
	});
	//监听用户退出
	socket.on('disconnect', function(){
		//将退出的用户从在线列表中删除
		if(onlineUsers.hasOwnProperty(socket.name)) {
			//退出用户的信息
			var obj = {userid:socket.name, username:onlineUsers[socket.name]};
			
			//删除
			delete onlineUsers[socket.name];
			//在线人数-1
			onlineCount--;
			//向所有客户端广播用户退出
			io.emit('logout', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
			console.log(obj.username+'退出了聊天室');
		}
	});
	//监听用户发布聊天内容
	socket.on('message', function(obj){
		//向所有客户端广播发布的消息
		io.emit('message', obj);
		console.log(obj.username+'说:'+obj.content);
	});
  
});
http.listen(process.env.PORT || 5050, function(){
	console.log('listening on *:5050');
});
 类似资料: