vue+websocket+express+mongodb实战项目(实时聊天)(一)

来源:互联网 发布:光的双缝干涉实验 知乎 编辑:程序博客网 时间:2024/06/17 18:27

vue+websocket+express+mongodb实战项目(实时聊天)(一)

在原来基础上增加了多个聊天室以及发送图片【vue+websocket+express+mongodb实战项目(实时聊天)(二)】
http://blog.csdn.net/blueblueskyhua/article/details/73250992
旧版聊天室地址:
https://github.com/hua1995116/webchat/tree/08ff845a2ca46c27a9024138d5b4173c89dd8056
新版地址:
https://github.com/hua1995116/webchat
—————————————————————————————
继上一个项目用vuejs仿网易云音乐(实现听歌以及搜索功能)后,发现上一个项目单纯用vue的model管理十分混乱,然后我去看了看vuex,打算做一个项目练练手,又不想做一个重复的项目,这次我就放弃颜值,打算走心派。结合了后台nodejs,以及数据库mongodb来开发了一个实时聊天系统。这个系统可以说是一统江山,也算是实现前端程序员的一个梦了,前后通吃。自认为是一个比全的项目。项目地址:https://github.com/hua1995116/webchat 觉得好的请顺手来个star。

这里写图片描述

技术栈

  • 前端 vue,vue-router ,vuex
  • 后端 nodejs,express
  • 数据库 mongodb
  • 通讯 websocket
  • 脚手架工具 vue-cli

结构
├─build
├─config
├─models(存放mongoose对象)
├─schemas(存放mongoose的schemas模型)
├─src
│ │ App.vue
│ │ main.js(主入口)
│ ├─assets
│ ├─components (组件)
│ ├─router(vue-router路由)
│ └─store(vuex)
└─static(静态资源)

首先用脚手架工具构建一个项目。像这样:

vue init webpack my-project-name

结构大致是这样的

这里写图片描述

好!既然我们是实战项目,我就不多说这些配置问题。不然又跑题了。不然又要被小哥哥小姐姐们打了。

这里写图片描述

前端

首先看src目录下的页面布局。
main.js// 主入口

import Vue from 'vue'import App from './App'import router from './router'import store from './store'// 使用museui组件import MuseUI from 'muse-ui'import 'muse-ui/dist/muse-ui.css'Vue.use(MuseUI)Vue.config.productionTip = false/* eslint-disable no-new */new Vue({  el: '#app',  router,  store,  template: '<App/>',  components: {App}})

我们为了让整个项目看起来漂漂亮亮的,所以选择了muse-ui,别说,这个UI框架是真的漂亮。不信大家可以看muse-ui。其余都是脚手架的默认配置。

route/router.js

import Vue from 'vue'import Router from 'vue-router'import Index from '@/components/Index'import Robot from '@/components/Robot'import Home from '@/components/Home'Vue.use(Router)export default new Router({  routes: [    {      path: '/',      name: 'Index',      component: Index    },    {      path: '/robot',      name: 'Robot',      component: Robot    },    {      path: '/home',      name: 'Home',      component: Home    }  ]})

大家可以看到一共有三个路由,没错,我们就是写了三块,第一块是和大家一起的聊天室,第二块是和我们可爱的大白聊天,也就是我们的图灵机器人。有空你也去搞一个耍耍。第三块就是我们的个人中心,虽然这一块没什么东西。但是毕竟好看,哦~忘了,我们是走心的,怎么可以只看脸。

components/Chat.vue

created() {    const that = this    this.socket = io.connect('http://qiufengh.com:8081')    this.socket.on('message', function(obj) {        that.$store.commit('addroomdetailinfos', obj)        window.scrollTo(0, 900000)    })    this.socket.on('logout', function (obj) {        that.$store.commit('setusers', obj)    })},
this.socket = io.connect('http://qiufengh.com:8081')

这一句,主要用于连接你当前的服务,到时候下载后面的项目时,记得改成自己的服务以及端口。因为是在Index和Chat都有设置,所以你需要在Index.vue和Chat里的connect都改成你自己的服务。socket.on()用于接受消息。socket.emit() 用于发送消息。不懂的socket.io的看这里socket.io。有了这个就可以和服务端进行交互。等会讲解服务端。

store/index.js

state: { //存放用户  user: {    name: '',    src: ''  },  //存放历史记录  messhistory: {    infos: []  },  //存放房间信息,为了方便以后做多房间  roomdetail: {    id: '',    users: {},    infos: []  },  //存放机器人开场白  robotmsg: [{    message: 'Hi~有什么想知道的可以问我',    user: 'robot'  }],  //聊天页面显示控制  chattoggle: false,  //登录页面显示控制  logintoggle: false,  //注册页面显示控制  registertoggle: true,  //提示框显示控制  dialog: false,   //提示框内容  dialoginfo: ''}

由于控制代码太多,所以之后的内容请大家移步,我的github地址。https://github.com/hua1995116/webchat/

服务器端

由于build下dev-server.js中webpack代码太多,太杂乱,不易于讲解。主要来看看用于打包后的服务器端。两份代码是一样的。
prod.server.js(根目录下)

var express = require('express');var config = require('./config/index');var port = process.env.PORT || config.dev.port;var app = express();var router = express.Router();//用于静态展示入口router.get('/',function(req,res,next){    req.url = './index.html';    next();});app.use(router);require('./config/routes')(app)/*引入*/var mongoose = require('mongoose')//日志文件var morgan = require('morgan')//sesstion 存储var bodyParser = require('body-parser')var cookieParser = require('cookie-parser')var session = require('cookie-session')//用于异步回调mongoose.Promise = require('bluebird')global.db = mongoose.connect("mongodb://localhost:27017/vuechat")//服务器提交的数据json化app.use(bodyParser.json())app.use(bodyParser.urlencoded({extended: true}))//sesstion 存储app.use(cookieParser())app.use(session({  secret: 'vuechat',  resave: false,  saveUninitialized: true}))var env = process.env.NODE_ENV || 'development'if ('development' === app.get('env')) {  app.set('showStackError', true)  app.use(morgan(':method :url :status'))  app.locals.pretty = true  mongoose.set('debug', true)}var server = app.listen(port)//websocket// var http = require('http').Server(app);var io = require('socket.io')(server);var Message = require('./models/message')var users = {}io.on('connection', function (socket) {  //监听用户发布聊天内容  socket.on('message', function (obj) {    //向所有客户端广播发布的消息    io.emit('message', obj)    var mess = {      username: obj.username,      src:obj.src,      msg: obj.msg,      roomid:'room1'    }    var message = new Message(mess)    //将发送过来的消息进行储存    message.save(function (err, mess) {      if (err) {        console.log(err)      }        console.log(mess)    })    console.log(obj.username + '说:' + obj.msg)  })  socket.on('login',function (obj) {    users[obj.name] = obj    //用于监听用户进行聊天室    io.emit('login', users)  })  socket.on('logout',function (name) {    delete users[name]    //用户监听用退出聊天室    io.emit('logout', users)  })})//声明静态资源地址app.use(express.static('./dist'));

schema模型

schema/user.js

var mongoose = require('mongoose')//用于md5加密var bcrypt = require('bcryptjs')//加盐数var SALT_WORK_FACTOR = 10var UserSchema = new mongoose.Schema({  name: {    unique: true,    type: String  },  password: String,  src: String,  meta: {    createAt: {      type: Date,      default: Date.now()    },    updateAt: {      type: Date,      default: Date.now()    }  }});//对密码进行加密UserSchema.pre('save', function (next) {  var user = this  if (this.isNew) {    this.createAt = this.updateAt = Date.now()  }  else {    this.updateAt = Date.now()  }  bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {    if (err) return next(err)    bcrypt.hash(user.password, salt, function (err, hash) {      if (err) return next(err)      user.password = hash      next()    })  })})//用于比较密码是否正确UserSchema.methods = {  comparePassword: function (_password, cb) {    bcrypt.compare(_password, this.password, function (err, isMatch) {      if (err) return cb(err)      cb(null, isMatch)    })  }}UserSchema.statics = {  fetch: function (cb) {    return this      .find({})      .sort('meta.updateAt')      .exec(cb)  },  findById: function (id, cb) {    return this      .findOne({_id: id})      .exec(cb)  }}module.exports = UserSchema

这里主要用到一个md5的模块,可以查看 bcryptjs

schema/message.js

var mongoose = require('mongoose')//聊天记录模型var MessageSchema = new mongoose.Schema({  username: String,  src:String,  msg: String,  roomid:String,  time: {    type: Date,    default: Date.now()  }})//静态方法MessageSchema.statics = {  fetch: function (cb) {    return this      .find({})      .sort('time')      .exec(cb)  },  findById: function (id, cb) {    return this      .findOne({_id: id})      .exec(cb)  }}module.exports = MessageSchema

服务器的routes
config/routes.js 讲一个注册的把,其他请前往项目查看

app.post('/user/signup', function (req, res) {    //获取提交数据    var _user = req.body    console.log(_user)    User.findOne({name: _user.name}, function (err, user) {      if (err) {        console.log(err)      }      if (user) {        res.json({          errno: 1,          data: '用户名已存在'        })      } else {        var user = new User(_user)        user.save(function (err, user) {          if (err) {            console.log(err)          }          res.json({            errno: 0,            data: '注册成功'          })        })      }    })  })

主要用于验证用户名是否重复。

核心部分就讲到这里啦,。其他具体的请查看我的github地址(具有详细的注释,不明白的可以提问,需要改进的请各位前辈指出):
地址:https://github.com/hua1995116/webchat
在线观看地址:http://www.qiufengh.com:8081/#/

npm install -----安装依赖npm run dev -----运行npm run build -----打包node prod.server.js -----打包后运行//记得替换Index.vue和Chat.vue下的io.connect('http://qiufengh.com:8081')http://qiufengh.com:8081改成自己的项目地址。

最后上几张图。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

6 0
原创粉丝点击