571
社区成员
发帖
与我相关
我的任务
分享本项目是一个基于web的实时聊天室项目,采用前后端分离的架构。使用vue作为前端框架完成客户端的开发,使用express作为后端框架完成服务端的开发,使用socket.io框架,通过WebSocket协议的方式实现前后端的数据交互。
主要业务逻辑为用户进入聊天室,客户端和服务器建立socket连接,并通过广播方式,发送给所有建立了socket连接的客户端新用户的信息;用户发送消息,客户端将消息发送给服务端,服务端通过广播将消息发送给每一个建立socket连接的客户端,使得每个用户都可以收到其他用户发送的消息,从而实现实时群聊功能。
Vue.js 是一个轻巧、高性能的MVVM 库。其核心在于数据双向绑定,即Model-View-ViewModel,将View和Model通过ViewModel进行绑定,View 的变化会自动同步到 Model,而 Model 的变化也会立即反映到 View 上显示。基于此,响应式是Vue.js的一大特点,当用户操作 View,ViewModel 感知到变化,然后通知 Model 发生相应改变;反之当 Model 发生改变,ViewModel 也能感知到变化,使 View 作出相应更新。
Vue的另一大特点是可组件化,允许采用简洁的模板来声明式地将数据渲染进DOM系统。组件一般包含template, script和style三部分,分别为组件的模板DOM结构,组件的 JavaScript 行为和组件的样式,采用面向对象的思想定义和使用组件,低耦合,重用性好。

Express是一个简单易上手的后端框架,基于node.js。Express提供了大量友好的API,通过官方文档,我们可以轻松实现基本路由,挂载路由模块,设置中间件来响应 HTTP请求。同时Express模板引擎,允许在应用程序中使用静态模板文件,在运行时,模板引擎用实际值替换模板文件中的变量,并将模板转换为发送客户端的HTML文件。Express方便快速搭建后端服务。
传统HTTP请求只能由浏览器发起,服务器无法发起HTTP请求,需要从HTTP服务器主动向浏览器推送消息。HTTP服务器只有通过轮询/心跳不断向服务器发送给HTTP请求,当HTTP服务器有消息要推送给客户端时就将消息放到HTTP响应中返回给HTTP客户端。
WebSocket协议最大特点是服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。WebSocket是建立在TCP协议之下的应用层协议;与Http协议有良好的兼容性,默认端口为80和443,握手阶段采用Http协议,因此握手时不容易屏蔽,能通过各种HTTP代理服务器;数据格式轻量,性能开销小,通信高效,可以发送文本,也可以发送二进制数据;没有类型Ajax有同源限制需要较为复杂的机制实现跨域访问,WebSocket客户端可以与任何服务器通信。
Socket.IO不仅仅是优秀的WebSocket服务端接口框架,还支持许多种轮询机制以及实时通信方式,当Socket.IO检测到当前环境不支持WebSocket时,能够自动选择最佳方式实现网络的实时通信。不同的方式客户端接口是不同的,Socket.IO将不同的方式客户端接口封装成统一的Socket.IO客户端接口,实现客户端和服务端双向通信。


用户需要输入自己的聊天室昵称,然后进入聊天室。浏览器需要先和服务器建立socket连接,接着浏览器向服务器发送用户消息,服务器收到消息后广播新用户进入聊天室消息。

服务端socket.io搭建
const app = require('express')
const server = require('http').Server(app)
const io = require('socket.io')(server)
//监听8081端口
server.listen(8081)
用户登录客户端代码
<script>
import io from 'socket.io-client'
// 建立socket.io通信
const socket = io.connect('http://localhost:8081')
export default {
name: 'Login',
components: {
About
},
data() {
return {
nickname: '',
isShowAbout: false
}
},
methods: {
enterChat() {
if (!this.nickname) {
return
}
this.$store.commit('setNickname', this.nickname)
this.$router.push('/Chat')
}
}
</script>
用户登录客户端代码
io.sockets.on('connection', socket => {
console.log('用户链接成功')
oSockets.push(socket)
// 上线
socket.on('online', data => {
//广播新用户上线
socket.broadcast.emit('online', data)
})
用户发送消息,浏览器将用户发送的消息发送给服务器,服务器向所有建立socket连接的客户端发送收到的消息,客户端收到消息后,更新消息列表。

客户端发送消息代码
sendMsg() {
if (!this.inputText) {
return
}
//向服务器发送消息
socket.emit('sendMsg', {
from: 'other',
date: this.getTime(),
nickname: this.nickname,
portrait: this.portrait,
location: this.location,
content: this.inputText
})
this.pushMine()
this.inputText = ''
this.isShowEmoji = false
this.$refs.inputBox.blur()
},
pushMine() {
this.messages.push({
from: 'mine',
date: this.getTime(),
nickname: this.nickname,
portrait: this.portrait,
content: this.inputText
})
},
//获取发送时间
getTime() {
return this.moment().format('YYYY-MM-DD HH:mm:ss')
},
//更新消息列表
fixedBottom() {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.$refs.chatContent.scrollTop = this.$refs.chatContent.scrollHeight
}, 20)
}
}
mounted() {
// 监听通信事件
socket.on('online', name => {
if (!name) {
return
}
this.onlineTip = `${name}加入群聊`
this.showTip()
})
socket.on('receiveMsg', data => {
this.messages.push(data)
})
}
服务端发送消息代码
// 群聊
Socket.on('sendMsg', data => {
socket.broadcast.emit('receiveMsg', data)
})



NP342