基于vue+express+socket.io的web聊天室

lghost1999 2022-01-17 20:37:10

1 整体介绍

本项目是一个基于web的实时聊天室项目,采用前后端分离的架构。使用vue作为前端框架完成客户端的开发,使用express作为后端框架完成服务端的开发,使用socket.io框架,通过WebSocket协议的方式实现前后端的数据交互。
主要业务逻辑为用户进入聊天室,客户端和服务器建立socket连接,并通过广播方式,发送给所有建立了socket连接的客户端新用户的信息;用户发送消息,客户端将消息发送给服务端,服务端通过广播将消息发送给每一个建立socket连接的客户端,使得每个用户都可以收到其他用户发送的消息,从而实现实时群聊功能。

2 技术介绍

2.1 Vue

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 行为和组件的样式,采用面向对象的思想定义和使用组件,低耦合,重用性好。

img

mvvm关系图

2.2 Express

Express是一个简单易上手的后端框架,基于node.js。Express提供了大量友好的API,通过官方文档,我们可以轻松实现基本路由,挂载路由模块,设置中间件来响应 HTTP请求。同时Express模板引擎,允许在应用程序中使用静态模板文件,在运行时,模板引擎用实际值替换模板文件中的变量,并将模板转换为发送客户端的HTML文件。Express方便快速搭建后端服务。

2.3 Socket.io

传统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客户端接口,实现客户端和服务端双向通信。

img

HTTP和WebSocket连接方式对比



3 功能介绍

img

系统用例图

3.1 用户登录

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

img

用户登录时序图

服务端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)
  })

3.2 发送消息

用户发送消息,浏览器将用户发送的消息发送给服务器,服务器向所有建立socket连接的客户端发送收到的消息,客户端收到消息后,更新消息列表。

img

发送消息时序图

客户端发送消息代码

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)
  })

4 项目运行

  • 用户登录
  • 用户聊天

NP342

...全文
264 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧