博客原文地址:http://www.cnblogs.com/qiufenghua/p/6772949.html,转载请注明出处。

在原来基础上增加了多个聊天室以及发送图片【vue+websocket+express+MongoDB实战项目(实时聊天)(二)】 
http://www.cnblogs.com/qiufenghua/p/7018886.html
旧版聊天室地址: 
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(静态资源)

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

  1. vue init webpack my-project-name

结构大致是这样的

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

前端

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

  1. import Vue from 'vue'
  2. import App from './App'
  3. import router from './router'
  4. import store from './store'
  5. // 使用museui组件
  6. import MuseUI from 'muse-ui'
  7. import 'muse-ui/dist/muse-ui.css'
  8. Vue.use(MuseUI)
  9. Vue.config.productionTip = false
  10.  
  11. /* eslint-disable no-new */
  12. new Vue({
  13. el: '#app',
  14. router,
  15. store,
  16. template: '<App/>',
  17. components: {App}
  18. })

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

route/router.js

  1. import Vue from 'vue'
  2. import Router from 'vue-router'
  3. import Index from '@/components/Index'
  4. import Robot from '@/components/Robot'
  5. import Home from '@/components/Home'
  6.  
  7. Vue.use(Router)
  8.  
  9. export default new Router({
  10. routes: [
  11. {
  12. path: '/',
  13. name: 'Index',
  14. component: Index
  15. },
  16. {
  17. path: '/robot',
  18. name: 'Robot',
  19. component: Robot
  20. },
  21. {
  22. path: '/home',
  23. name: 'Home',
  24. component: Home
  25. }
  26. ]
  27. })

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

components/Chat.vue

  1. created() {
  2. const that = this
  3. this.socket = io.connect('http://qiufengh.com:8081')
  4. this.socket.on('message', function(obj) {
  5. that.$store.commit('addroomdetailinfos', obj)
  6. window.scrollTo(0, 900000)
  7. })
  8. this.socket.on('logout', function (obj) {
  9. that.$store.commit('setusers', obj)
  10. })
  11. },
  1. 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

  1. state: {
  2. //存放用户
  3. user: {
  4. name: '',
  5. src: ''
  6. },
  7. //存放历史记录
  8. messhistory: {
  9. infos: []
  10. },
  11. //存放房间信息,为了方便以后做多房间
  12. roomdetail: {
  13. id: '',
  14. users: {},
  15. infos: []
  16. },
  17. //存放机器人开场白
  18. robotmsg: [{
  19. message: 'Hi~有什么想知道的可以问我',
  20. user: 'robot'
  21. }],
  22. //聊天页面显示控制
  23. chattoggle: false,
  24. //登录页面显示控制
  25. logintoggle: false,
  26. //注册页面显示控制
  27. registertoggle: true,
  28. //提示框显示控制
  29. dialog: false,
  30. //提示框内容
  31. dialoginfo: ''
  32. }

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

服务器端

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

  1. var express = require('express');
  2. var config = require('./config/index');
  3. var port = process.env.PORT || config.dev.port;
  4.  
  5. var app = express();
  6.  
  7. var router = express.Router();
  8. //用于静态展示入口
  9. router.get('/',function(req,res,next){
  10. req.url = './index.html';
  11. next();
  12. });
  13.  
  14. app.use(router);
  15.  
  16. require('./config/routes')(app)
  17. /*引入*/
  18. var mongoose = require('mongoose')
  19. //日志文件
  20. var morgan = require('morgan')
  21. //sesstion 存储
  22. var bodyParser = require('body-parser')
  23. var cookieParser = require('cookie-parser')
  24. var session = require('cookie-session')
  25. //用于异步回调
  26. mongoose.Promise = require('bluebird')
  27. global.db = mongoose.connect("mongodb://localhost:27017/vuechat")
  28.  
  29. //服务器提交的数据json化
  30. app.use(bodyParser.json())
  31. app.use(bodyParser.urlencoded({extended: true}))
  32. //sesstion 存储
  33. app.use(cookieParser())
  34. app.use(session({
  35. secret: 'vuechat',
  36. resave: false,
  37. saveUninitialized: true
  38. }))
  39.  
  40. var env = process.env.NODE_ENV || 'development'
  41. if ('development' === app.get('env')) {
  42. app.set('showStackError', true)
  43. app.use(morgan(':method :url :status'))
  44. app.locals.pretty = true
  45. mongoose.set('debug', true)
  46. }
  47.  
  48. var server = app.listen(port)
  49.  
  50. //websocket
  51. // var http = require('http').Server(app);
  52. var io = require('socket.io')(server);
  53. var Message = require('./models/message')
  54. var users = {}
  55. io.on('connection', function (socket) {
  56. //监听用户发布聊天内容
  57. socket.on('message', function (obj) {
  58. //向所有客户端广播发布的消息
  59. io.emit('message', obj)
  60. var mess = {
  61. username: obj.username,
  62. src:obj.src,
  63. msg: obj.msg,
  64. roomid:'room1'
  65. }
  66. var message = new Message(mess)
  67. //将发送过来的消息进行储存
  68. message.save(function (err, mess) {
  69. if (err) {
  70. console.log(err)
  71. }
  72. console.log(mess)
  73. })
  74. console.log(obj.username + '说:' + obj.msg)
  75. })
  76. socket.on('login',function (obj) {
  77. users[obj.name] = obj
  78. //用于监听用户进行聊天室
  79. io.emit('login', users)
  80. })
  81. socket.on('logout',function (name) {
  82. delete users[name]
  83. //用户监听用退出聊天室
  84. io.emit('logout', users)
  85. })
  86. })
  87.  
  88. //声明静态资源地址
  89. app.use(express.static('./dist'));

schema模型

schema/user.js

  1. var mongoose = require('mongoose')
  2. //用于md5加密
  3. var bcrypt = require('bcryptjs')
  4. //加盐数
  5. var SALT_WORK_FACTOR = 10
  6. var UserSchema = new mongoose.Schema({
  7. name: {
  8. unique: true,
  9. type: String
  10. },
  11. password: String,
  12. src: String,
  13. meta: {
  14. createAt: {
  15. type: Date,
  16. default: Date.now()
  17. },
  18. updateAt: {
  19. type: Date,
  20. default: Date.now()
  21. }
  22. }
  23. });
  24. //对密码进行加密
  25. UserSchema.pre('save', function (next) {
  26. var user = this
  27. if (this.isNew) {
  28. this.createAt = this.updateAt = Date.now()
  29. }
  30. else {
  31. this.updateAt = Date.now()
  32. }
  33. bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
  34. if (err) return next(err)
  35.  
  36. bcrypt.hash(user.password, salt, function (err, hash) {
  37. if (err) return next(err)
  38.  
  39. user.password = hash
  40. next()
  41. })
  42. })
  43. })
  44. //用于比较密码是否正确
  45. UserSchema.methods = {
  46. comparePassword: function (_password, cb) {
  47. bcrypt.compare(_password, this.password, function (err, isMatch) {
  48. if (err) return cb(err)
  49. cb(null, isMatch)
  50. })
  51. }
  52. }
  53.  
  54. UserSchema.statics = {
  55. fetch: function (cb) {
  56. return this
  57. .find({})
  58. .sort('meta.updateAt')
  59. .exec(cb)
  60. },
  61. findById: function (id, cb) {
  62. return this
  63. .findOne({_id: id})
  64. .exec(cb)
  65. }
  66. }
  67.  
  68. module.exports = UserSchema

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

schema/message.js

  1. var mongoose = require('mongoose')
  2. //聊天记录模型
  3. var MessageSchema = new mongoose.Schema({
  4. username: String,
  5. src:String,
  6. msg: String,
  7. roomid:String,
  8. time: {
  9. type: Date,
  10. default: Date.now()
  11. }
  12. })
  13. //静态方法
  14. MessageSchema.statics = {
  15. fetch: function (cb) {
  16. return this
  17. .find({})
  18. .sort('time')
  19. .exec(cb)
  20. },
  21. findById: function (id, cb) {
  22. return this
  23. .findOne({_id: id})
  24. .exec(cb)
  25. }
  26. }
  27. module.exports = MessageSchema

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

  1. app.post('/user/signup', function (req, res) {
  2. //获取提交数据
  3. var _user = req.body
  4. console.log(_user)
  5. User.findOne({name: _user.name}, function (err, user) {
  6. if (err) {
  7. console.log(err)
  8. }
  9. if (user) {
  10. res.json({
  11. errno: 1,
  12. data: '用户名已存在'
  13. })
  14. } else {
  15. var user = new User(_user)
  16. user.save(function (err, user) {
  17. if (err) {
  18. console.log(err)
  19. }
  20. res.json({
  21. errno: 0,
  22. data: '注册成功'
  23. })
  24. })
  25. }
  26. })
  27. })

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

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

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

最后上几张图。

vue+websocket+express+mongodb实战项目(实时聊天)的更多相关文章

  1. vue+websocket+express+mongodb实战项目(实时聊天)(二)

    原项目地址:[ vue+websocket+express+mongodb实战项目(实时聊天)(一)][http://blog.csdn.net/blueblueskyhua/article/deta ...

  2. vue+nodejs+express解决跨域问题

    nodejs+express解决跨域问题,发现网上的大部分都是误导人,花了不少时间,终于弄懂了, 我在vue+nodejs+express+mongodb的项目里面,发现本地用vue代理正常调用远程的 ...

  3. 15-Flink实战项目之实时热销排行

    戳更多文章: 1-Flink入门 2-本地环境搭建&构建第一个Flink应用 3-DataSet API 4-DataSteam API 5-集群部署 6-分布式缓存 7-重启策略 8-Fli ...

  4. SpringBoot+Vue+WebSocket 实现在线聊天

    一.前言 本文将基于 SpringBoot + Vue + WebSocket 实现一个简单的在线聊天功能 页面如下: 在线体验地址:http://www.zhengqingya.com:8101 二 ...

  5. Node+Express+MongoDB + Socket.io搭建实时聊天应用实战教程(二)--node解析与环境搭建

    前言 本来开始写博客的时候只是想写一下关于MongoDB的使用总结的,后来觉得还不如干脆写一个node项目实战教程实战.写教程一方面在自己写的过程中需要考虑更多的东西,另一方面希望能对node入门者有 ...

  6. Node+Express+MongoDB+Socket.io搭建实时聊天应用实战教程(一)--MongoDB入门

    前言 本文并不是网上流传的多少天学会MongoDB那种全面的教程,而意在总结这几天使用MongoDB的心得,给出一个完整的Node+Express+MongoDB+Socket.io搭建实时聊天应用实 ...

  7. 一个关于vue+mysql+express的全栈项目(五)------ 实时聊天部分socket.io

    一.基于web端的实时通讯,我们都知道有websocket,为了快速开发,本项目我们采用socket.io(客户端使用socket.io-client) Socket.io是一个WebSocket库, ...

  8. Node+Express+MongoDB + Socket.io搭建实时聊天应用实战教程(三)--前后端环境配置

    前言 之前都是介绍一些基础知识,在这一节,我们就要开始实战coding了.正所谓磨刀不误砍柴工,准备工作显得尤为重要.很多demo只是追求效果的实现,并不注重整个demo的架构性.从我个人的角度看来, ...

  9. Node+Express+MongoDB + Socket.io搭建实时聊天应用

    Node+Express+MongoDB + Socket.io搭建实时聊天应用 前言 本来开始写博客的时候只是想写一下关于MongoDB的使用总结的,后来觉得还不如干脆写一个node项目实战教程实战 ...

随机推荐

  1. 腾讯云数据库团队:浅谈如何对MySQL内核进行深度优化

    作者介绍:简怀兵,腾讯云数据库团队高级工程师,负责腾讯云CDB内核及基础设施建设:先后供职于Thomson Reuters和YY等公司,PTimeDB作者,曾获一项发明专利:从事MySQL内核开发工作 ...

  2. 2431: [HAOI2009]逆序对数列

    2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 954  Solved: 548[Submit][Status ...

  3. Java数据结构之Set学习总结

    前言: 前面介绍了Java的数据结构List.Map,今天抽空学习总结一下另一种数据结构Set. Set介绍 Set相对于List.Map是最简单的一种集合.集合中的对象不按特定的方式排序,并且没有重 ...

  4. sys模块和Python常用的内建函数

    1.sys模块 当Python执行import sys语句的时候,它在sys.path变量中所列目录中寻找sys.py模块.如果找到了这个文件,这个模块的主块中的语句将被运行,然后这个模块将能够被使用 ...

  5. Java synchronized 关键字的实现原理

    数据同步需要依赖锁,那锁的同步又依赖谁?synchronized给出的答案是在软件层面依赖JVM,而Lock给出的方案是在硬件层面依赖特殊的CPU指令,大家可能会进一步追问:JVM底层又是如何实现sy ...

  6. 3-14 JS基础知识01

    JavaScript的组成: JS特点:JS是一门 脚本语言:不需要编译编译:把代码转化成计算机所认知的二进制语言.JS是一门弱类型语言:声明变量都用varJS是一种动态语言:认知当前的着这个变量到底 ...

  7. PHP语言开发微信公众平台(订阅号)之开启基本功能及获得可用的服务器地址(2)

    1.开启群发功能(单击功能菜单里的"群发功能",并在右侧页面中点击"同意以上声明") 2.(1)在开启开发者模式之前需要完善个人资料(完成头像上传即可) (2) ...

  8. 因为本地没有配置 localhost 导致的 eclipse 的奇葩问题

    因为电脑没有配置 127.0.0.1 localhost,已经碰到两次奇葩问题了. 问题一: 我的博文http://www.cnblogs.com/sonofelice/p/5143746.html中 ...

  9. MCMC(一)蒙特卡罗方法

    MCMC(一)蒙特卡罗方法 MCMC(二)马尔科夫链(待填坑) MCMC(三)M-H采样和Gibbs采样(待填坑) 作为一种随机采样方法,马尔科夫链蒙特卡罗(Markov Chain Monte Ca ...

  10. [微信小程序]初试——成绩分析小程序问题总结

    文件类型说明 第一次打开微信小程序的开发者工具,就是下面这个样子. 好多已经存在的默认文件 .js .json .wxml .wxss 首先当然要搞懂这些文件都是干什么的 app.js是小程序的脚本代 ...