简约版聊天室

1.案例描述

本次项目利用express与socket.js
实现简约版聊天室,有用户登录及提示
用户退出及提示。聊天的显示

聊天室

2.静态页面

该页面主要有四大块区域
头部用户输入登录与退出功能
左侧用户聊天显示区域
右侧用户列表显示区域
底部用户输入聊天内容区域

2.1功能描述

当用户在头部的输入框输入内容
后,点击登录,右侧列表出现用户名字
左侧出现登录提示。点击底部输入聊天内容
点击发送左侧出现该用户的聊天内容。
点击头部退出按钮时用户列表该用户退出
左侧显示退出提示。

2.2静态页面代码

HTML:

<body onload="window_onload()" onunload="window_onunload()"><h1>聊天室</h1><div id="divContainer1"><table id="tbDlg" border="0" cellpadding="3" cellspacing="0" width="100%"><tr id="trDlg"><td id="tdDlg" width="5">用户名:&nbsp;<input type="text" value="游客" size="20" id="tbxUsername"><input type="button" id="btnLogin" value="登录" onclick="btnLogin_onclick()"><input type="button" id="btnLogout" onclick="btnLogout_onclick()" disabled value="退出"></td></tr></table></div><div id="divLeft"><div id="divchat"></div><div id="divContainer3"><table id="tbDlg" border="0" cellpadding="3" cellspacing="0" width="0"><tr id="trDlg"><td valign="top" id="tdDlg" nowarp>对话</td><td valign="top" id="tdDlg" ><textarea id="tbxMsg" cols="255" rows="5" style="width:100%"></textarea></td><td valign="top" id="tdDlg" nowarp><input type="button" id="btnSend" value="发送" disabled onclick="btnSend_onclick()"></td></tr></table></div></div><div id="divRight">用户列表:</div></body><script src="/socket.io/socket.io.js"></script>

css:

h1{font-size: 14pt;color:#006bb5;background-color: #f0f0f0;border:1px solid #f0f0f0;padding:5px;margin-bottom: 18px;border-radius: 5px;color:purple}div[id^=divContainer]{border:0;margin:10px 0px 10px 0px;padding:3px;background-color: #f0f0f0;border-radius: 5px;}div#divLeft{width:85%;background-color: #f0f0f0;float: left;}div#divright{width:15%;background-color: white;float: right;font-size: 14px;}div#divchat{border:0;margin:10px 0 10px 0;padding:3px;background-color: #f0f0f0;border-radius: 5px;position: relative;height:300px;overflow: auto;font-size: 14px;font-size: 16px;}table#tbDlg{background-color: #f0f0f0;font-size: 14px;}tr#trDlg,td#tdDlg{font-size: 14px;}textarea{border:1px solid #444;border-radius: 10px;margin:5px;color:black;background-color: white;width:100px;font-size:16px;}input[type="button"]{border:1px solid #808080;border-radius: 20px;width:80px;background-color: #81a0b5;}input[type="button"]:hover{background-color: #006bb5;}input[type="button"]:active{margin:1px;font-weight: bold;background-color: #006bb5;}input[type="button"]:focus{margin:0;font-weight: bold;background-color: #006bb5;}

3.服务端代码

下载express npm i express
下载socket.io npm i socket.io

关于socket的使用,可参考官网

const express = require('express');const app = express();const http = require('http');const server = http.createServer(app);const { Server } = require("socket.io");const io = new Server(server);app.use(express.static(__dirname)); app.get('/',(req,res)=>{res.sendFile(__dirname+'./index.html')})server.listen(8081,()=>{console.log("it is ok")})var names=[]io.sockets.on('connection',(socket)=>{socket.on('login',name=>{for(var i=0;i<names.length;i++){if(names[i]==name){socket.emit('duplicate')return}}names.push(name)io.sockets.emit('login',name)io.sockets.emit('sendClients',names)})socket.on('chat',data=>{io.sockets.emit('chat',data)console.log(data)})socket.on('logout',name=>{for(var i=0;i<names.length;i++){if(names[i]==name){names.splice(i,1)break}}socket.broadcast.emit('logout',name)io.sockets.emit('sendClients',names)})})

代码解析

该后端代码中,用names数组存放所有登录的用户名,用户登录时客户端与服务端建立连接,指定服务器接收到登录事件时(login)的处理逻辑。比如用户是否重复,发送duplicate事件。如果一切正常服务端发送sendClient事件
用来更新用户列表。当用户输入聊天内容后点击发送向服务器发送chat事件。服务端接收后向所有客户端发送chat事件。当用户点击退出
是向服务器发送logout事件,服务端接收,向所有客户端发送logout事件,以便处理用户退出后的逻辑。最后向所有客户端发送sendClients事件,实现界面更新。

4.js部分

启动只需在该文件所在目录终端
输入node server.js(你存放服务器代码文件的名字)
之后在游览器输入服务器监听的端口号

var userName,socket,tbxUsername,tbxMsg,divChatfunction window_onload(){divChat=document.getElementById('divchat')tbxUsername=document.getElementById('tbxUsername')tbxMsg=document.getElementById('tbxMsg')tbxUsername.focus()tbxUsername.select()}var color=['green','#006bb5','brown','crimson','purple']function AddMsg(msg){console.log(parseInt(Math.random(0,1)*color.length))divChat.innerHTML+=msg+'
'
divChat.style.color=color[parseInt(Math.random(0,1)*color.length)]if(divChat.scrollHeight>divChat.clientHeight){divChat.scrollTop=divChat.scrollHeight-divChat.clientHeight}}function btnLogin_onclick(){if(tbxUsername.value.trim()==''){alert('请输入用户名')return}socket =io()userName=tbxUsername.value.trim()socket.on('connect',function(){AddMsg('连接聊天服务器')socket.on('login',function(name){AddMsg('欢迎'+name+'进入')})socket.on('sendClients',function(names){var divRight=document.getElementById('divRight')var str=''names.forEach((name)=>{str+=name+'
'
})divRight.innerHTML="用户列表:
"
divRight.innerHTML+=str})socket.on("chat",data=>{AddMsg(data.user+'说:'+data.msg)})socket.on("disconnect",()=>{AddMsg("与服务器断开连接")document.getElementById('btnSend').disabled=truedocument.getElementById('btnLogout').disabled=truedocument.getElementById('btnLogin').disabled=''var divRight=document.getElementById('divRight')divRight.innerHTML="用户列表"})socket.on("logout",name=>{AddMsg("用户"+name+'已退出')})socket.on("duplicate",()=>{AddMsg("改用户名已被使用")document.getElementById('btnSend').disabled=truedocument.getElementById('btnLogout').disabled=truedocument.getElementById('btnLogin').disabled=''divRight.innerHTML="用户列表"})})socket.on("error",()=>{AddMsg("与服务器连接失败") socket.disconnect() socket.removeAllListeners("connect") io.sockets={}})socket.emit('login',userName)document.getElementById('btnSend').disabled=''document.getElementById('btnLogout').disabled=''document.getElementById('btnLogin').disabled=true}function btnSend_onclick(){var msg=tbxMsg.value socket =io()if(msg.length>0){socket.emit('chat',{user:userName,msg:msg})tbxMsg.value=''}}function btnLogout_onclick(){ socket =io()socket.emit('logout',userName)socket.disconnect()io.socket={}AddMsg("用户"+userName+'已退出')var divRight=document.getElementById('divRight')divRight.innerHTML="用户列表"document.getElementById('btnSend').disabled='disabled'document.getElementById('btnLogout').disabled='disabled'document.getElementById('btnLogin').disabled=''}function window_onunload (){socket.emit('logout',userName)socket.disconnect()}

代码解析:
主要有六大函数,

window_onload用与文档一加载变后去对应的元素
AddMsg用于将用户输入的文字,服务器返回的信息进行显示
btnLogin_onclick用于与服务器建立连接,监听sendClients,login,chart等事件用于进行相应的js操作
btnSend_onclick向服务器发送输入框的文字
btnLogout_onclick断开与服务器的连接,进行html样式的改写
window_onunload