技术概述
- 前端框架:Vue —— Vue是基于标准HTML、CSS和JavaScript构建,并提供了一套声明式的、组件化的编程模型,帮助开发者高效地开发用户界面,无论任务是简单还是复杂。Vue是一个轻量级、灵活的JavaScript框架,用于构建用户界面和单页应用。它的核心库关注视图层,易于上手和整合,同时也能够满足复杂应用的需求。Vue的核心库只关注视图层,易于上手,也便于与第三方库或既有项目整合
- 后端框架:Express —— Express 是一个基于Node.js的快速、简洁的web开发框架。它提供了一系列强大的特性,使开发者能够快速地构建健壮、可扩展的web应用。通过简单的API和丰富的扩展库,开发者可以快速地开发出符合需求的web应用。
- 数据库:MongoDB ——MongoDB是一个开源的、跨平台的、面向文档的、基于分布式文件存储的数据库系统。它使用C++语言编写,旨在为Web应用提供可扩展的高性能数据存储解决方案。它提供了强大的查询语言和各种扩展功能,使得开发者可以快速地构建出高效、可扩展的Web应用。
- 通信:Socket —— Socket是网络编程中的重要概念,它提供了一种方便、高效的网络通信方式,使得应用程序可以轻松地实现各种网络协议和数据传输需求。应用程序通常通过“套接字”向服务器发出请求或者应答网络请求。在网络通信中,每个Socket都有一个与之关联的IP地址和端口号。
部分代码展示
前端主要设计
登录界面
这段代码是Vue组件中用于处理用户登录,使用axios进行HTTP请求,通过WebSocket通知服务器有用户登录,在登录成功后导航到/chat/${username}路径,并向服务器发送一个消息,告诉服务器有一个用户登录了。
this.$axios.get('/login', { params: params })
.then(function (res) {
if (res.data.success) {
_this.$router.push({ path: `/chat/${username}` })
_this.$socket.emit('login', _this.loginForm.username) // 向后台通知有用户登录
} else {
_this.$message.error(res.data.message)
}
})
.catch(function (err) {
console.log(err)
})
聊天界面
这段代码重新定义了一个Vue组件,用于处理实时聊天室的逻辑,包括用户连接、断开、发送消息等操作。其中使用到了WebSocket(通过Socket.IO库)进行实时通信,以及实现了本地存储(localStorage)来保存聊天历史记录。
sockets: {
connect () {
},
disconnect () {
},
user_enter (data) {
this.chatHistory.push(data)
localStorage.setItem('chatHistory', JSON.stringify(this.chatHistory))
},
user_leave (data) {
this.chatHistory.push(data)
localStorage.setItem('chatHistory', JSON.stringify(this.chatHistory))
},
count_users (data) {
this.count = data.length
this.userList = data
},
broadcast_msg (data) {
this.chatHistory.push(data)
console.log(this.chatHistory)
localStorage.setItem('chatHistory', JSON.stringify(this.chatHistory))
}
},
methods: {
sendMsg () {
if (this.input.trim() === '') {
return
}
console.log(this.input)
this.$socket.emit('send_msg', { // 通知后台广播消息
username: this.currentUser,
input: this.input.trim()
})
this.input = ''
},
}
}
后端主要设计
登录
当客户端发送login事件时,服务器会接收一个包含用户名的数据对象。服务器首先检查该用户是否已存在。如果用户存在,则向该客户端发送一个loginError事件并打印相关日志;如果不存在,则将该用户添加到users列表中,并向所有在线客户端广播该用户已加入的消息,并更新用户数量。
module.exports = function (server) {
var io = require('socket.io')(server, {
allowEIO3: true,
cors: {
origin: true,
credentials: true
}
});
let count = 0 // 当前群聊用户数量
let users = [] // 当前群聊用户
io.on('connection', (socket) => {
count++
console.log('user connected')
socket.on('login', (data) => {
socket.username = data
console.log(`用户【${data}】加入了聊天室`)
const user = users.find(item => item === data)
if (user) {
socket.emit('loginError')
console.log(user)
}else {
users.push(data)
console.log(users)
io.sockets.emit('user_enter', `用户【${data}】加入了聊天室`)
io.sockets.emit('count_users', users) // 更新当前用户
}
})
socket.on('send_msg', (data) => {
console.log(`收到客户端的消息:${data}`)
io.sockets.emit('broadcast_msg', { // 向所有在线用户发消息
username: data.username,
input: data.input,
time: new Date().toLocaleString()
})
})
socket.on('disconnect', () => {
let index = users.findIndex(item => item === socket.username)
users.splice(index, 1)
console.log('user disconnected')
io.sockets.emit('user_leave', `用户【${socket.username}】离开了聊天室`)
io.sockets.emit('count_users', users)
});
})
}
登录和注册过程的报错
这段代码则是将登录过程和注册过程中可能出现的错误都会出现相应的报错
var express = require('express');
var router = express.Router();
// get the model of user
var User = require('../database/user_model');
/* login */
router.get('/login', function(req, res, next) {
User.find({
username: req.query.username,
password: req.query.password
}, (err, docs) => {
if (err) {
res.send({ success: false, message: '系统错误!' });
} else if (docs.length == 0) {
res.send({ success: false, message: '此用户不存在!' });
} else {
res.send({ data: docs[0], success: true, message: '登录成功!' });
}
});
});
/* register */
router.post('/register', function(req, res, next) {
User.find({
username: req.query.username
}, (err, docs) => {
if (err) {
res.send({success: false, message: '系统错误!' });
} else if (docs.length == 0) {
new User({
username: req.query.username,
password: req.query.password,
phone: req.query.password
}).save((err) => {
if (err) {
res.send({ success: false, message: '注册失败!' });
} else {
res.send({ success: true, message: '注册成功!' });
}
});
} else {
res.send({ success: false, message: '此用户已存在,请登录!' });
}
});
});
运行展示
用户注册页面
用户在这里输入自己的用户名和密码以及手机号,若是在数据库中没有出现一样的用户名或者手机号,则会注册成功,相应的数据库中也会多一条用户的信息。
用户登录界面
用户在登录的过程中,会将用户名放到数据库中去查询,如果密码与数据库中存储的一直,则会登录成功,否则会出现密码错误或未注册的错误提示。
聊天室界面
聊天室则是实现了多人同时聊天,以及历史消息和私聊的功能,我们会将用户发的每一条消息存储到数据库中,并将其存储为历史消息,同时在私聊过程中,用户也能完成对私聊信息的存储。
课程总结
回顾这门课程的学习历程,我深感收获颇丰。通过学习网络程序设计,我不仅掌握了基本的网络编程技术,还培养了解决实际问题的能力。在这我要感谢孟宁老师上课的幽默风趣的氛围,让我们能够更快的接受知识。在未来的学习和工作中,我将继续努力,将所学知识运用到实践中,也希望能够在课程中深入学习更多高级的网络编程技术和Web开发框架,以更好地适应市场需求和职业发展需要。