前言
源码获取: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获取usernamevar 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.inpvalul.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.destip.className = "tips"ul.appendChild(tip)people.innerHTML = '(' + msg.count + ')'})} else {window.location.href = "/login.html"}</script></html>
联系方式
v:13053025350,欢迎询问,也欢迎接单选手>>>>>