前言
源码获取:node+express+socket.io+web: 聊天demo (gitee.com)
目录结构
后端依赖
启动方式
前端是html正常启动
后端是node app.js
后端app.js核心代码
const express = require('express')
const app = express()
var http = require('http').Server(app)
var io = require('socket.io')(http, { cors: true })
var name = ""
var count = 0
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
app.get('/',(req,res)=>{
// 保存用户的名称
name = req.query.username
// 返回状态码,通过状态码执行客户端页面跳转
res.send({state:200})
// res.sendFile(__dirname + '/index.html')
})
//入口函数,连接进程
io.on('connection', function (socket) {
// 每建立连接一次,在线人数减一
count++
//这里是发送消息
// on用来监听客户端message事件,回调函数处理。
socket.on('message', function (msg) {
// 如果在这里通过url解析的username来改变下面33行即将渲染的name,会出现异步问题。name还没有赋值就被传到客户端
// 所以通过ajax请求,先让后端拿到username,然后再做提示信息的渲染
console.log(msg.username+':'+ msg.inpval);
// 将客户端发送来的消息中转给所有客户端
io.emit('message', msg)
});
// loginin是自定义事件,第二个参数返回数据对象用于渲染,用于登陆后向客户端发送用户登录信息
io.emit('loginin',{count,des:'温馨提示:'+name+'加入聊天室'})
//登陆后向客户端发送用户退出信息
socket.on('disconnect', function () {
// loginout是自定义事件,第二个参数返回数据对象用于渲染
count--
io.emit('loginout',{count,des:'温馨提示:'+name+'用户退出聊天室'})
// 连接每断开一次,在线人数减一
})
});
http.listen(3000, function () {
console.log('listening:3000')
})
html部分
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.chat {
width: 400px;
margin: 0 auto;
border: 1px solid #333;
}
.title {
line-height: 30px;
color: black;
border-bottom: 1px solid #999;
text-align: center;
}
.content {
width: 100%;
overflow: auto;
height: 500px;
}
#messages li {
list-style: none;
padding: 5px;
}
#m {
width: 80%;
height: 30px;
outline: none;
color: #666
}
#btn {
width: 20%;
height: 30px;
cursor: pointer;
}
.tips {
width: 50%;
margin: 4px auto;
padding: 2px 5px;
text-align: center;
font-size: 8px;
border-radius: 10px;
background-color: #cfcfcf;
color: #fff
}
.title #people {
font-size: 8px;
color: #999;
}
</style>
</head>
<body>
<div class="chat">
<div class="title">
<h3>聊天室<span id="people">(0)</span></h3>
</div>
<div class="content">
<ul id="messages">
</ul>
</div>
<input id="m" autocomplete="off" /><button id="btn">Send</button>
</div>
</body>
<script src="./static/dist/socket.io.js"></script>
<script>
// 通过url获取username
var test = window.location.href;
var username = decodeURI(test.split("?username=")[1]);
// 做个判断
if (localStorage.getItem('username') != '') {
var socket = io('http://localhost:3000/')
var btn = document.getElementById('btn')
var ul = document.getElementById('messages')
let cxt = document.getElementById('m')
let people = document.getElementById('people')
// 点击send按钮,把消息发送给服务器
btn.onclick = function () {
// 把登录的用户名和输入框内容全部发送给服务器,让服务器做一次广播,才能同步用户信息。
socket.emit('message', { username, inpval: cxt.value })
return false
}
//监听服务器的广播消息,同步用户信息,msg就是点击发送按钮发送的用户信息
socket.on('message', function (msg) {
// 每个客户端将用户的消息渲染
var newli = document.createElement("li")
newli.innerHTML = msg.username + ':' + msg.inpval
ul.appendChild(newli)
cxt.value = ''
})
// 服务器端监听服务端建立连接发来的信息,用于渲染温馨提示信息,msg是服务器返回广播的用户对象数据
socket.on("loginin", function (msg) {
// 生成用户进入房间提示信息标签
let tip = document.createElement("p")
tip.innerHTML = msg.des
// 设置样式
tip.className = "tips"
ul.appendChild(tip)
// people是显示当前聊天室人数
people.innerHTML = '(' + msg.count + ')'
})
//服务器端监听服务端建立连接发来的信息,msg是服务器返回广播的用户对象数据
socket.on("loginout", function (msg) {
// 生成用户退出提示信息
let tip = document.createElement("p")
tip.innerHTML = msg.des
tip.className = "tips"
ul.appendChild(tip)
people.innerHTML = '(' + msg.count + ')'
})
} else {
window.location.href = "/login.html"
}
</script>
</html>
联系方式
v:13053025350,欢迎询问,也欢迎接单选手>>>>>