阿里云优惠活动,点击链接进行购买: 一年仅需96.9元即可以购买服务器~

腾讯云优惠活动, 点击链接进行购买一年仅需99元

腾讯云限时开团活动, 点击链接进行购买一年仅需95元

各大服务器厂商对比选购

# 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 仿网易云音乐(实现听歌以及搜索功能) (opens new window)后,发现上一个项目单纯用 vue 的 model 管理十分混乱,然后我去看了看 vuex,打算做一个项目练练手,又不想做一个重复的项目,这次我就放弃颜值,打算走心派。结合了后台 nodejs,以及数据库 mongodb 来开发了一个实时聊天系统。这个系统可以说是一统江山,也算是实现前端程序员的一个梦了,前后通吃。自认为是一个比全的项目。项目地址:https://github.com/hua1995116/webchat (opens new window) 觉得好的请顺手来个 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 (opens new window)。其余都是脚手架的默认配置。

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

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

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 (opens new window)。有了这个就可以和服务端进行交互。等会讲解服务端。

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/ (opens new window)

服务器端

由于 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 = 10;
var 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 (opens new window)

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 (opens new window) 在线观看地址:http://www.qiufengh.com:8081/#/ (opens new window)

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改成自己的项目地址。

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

Last Updated: 9/12/2022, 3:03:48 PM