原項目地址:
【 vue+websocket+express+mongodb實戰項目(實時聊天)(一)】
http://blog.csdn.net/blueblueskyhua/article/details/70807847
github地址: https://github.com/hua1995116/webchat
在線演示地址:http://www.qiufengh.com:8081/#/
在原項目(vue+websocket+express+mongodb實戰項目(實時聊天)(一))的基礎上,我又繼續開發,增加了兩個新功能,多個聊天室以及上傳圖片功能。覺得不錯可以關注我,點波star。這個項目我會繼續更新的。
###多個聊天室
首先我們先來看看socket.io的 API
加入某個分組
io.on('connection', function(socket){
socket.join('some room');
});
向某個分組發送消息
io.to('some room').emit('some event');
而在我們這邊也是一樣的。
build/der-server.js
socket.on('login',function (obj) {
socket.name = obj.name
socket.room = obj.roomid
if (!global.users[obj.roomid]) {
global.users[obj.roomid] = {}
}
global.users[obj.roomid][obj.name] = obj
socket.join(obj.roomid)
io.to(obj.roomid).emit('login', global.users[obj.roomid])
console.log(obj.name + '加入了' + obj.roomid)
})
當一個用戶加入一個房間時。讓他加入一個分組。當然我們需要用戶在加入的時候傳遞一個參數,房間名。
socket.on('message', function (obj) {
//向所有客戶端廣播發布的消息
var mess = {
username: obj.username,
src:obj.src,
msg: obj.msg,
img: obj.img,
roomid: obj.room
}
io.to(mess.roomid).emit('message', mess)
console.log(obj.username + '對房' + mess.roomid+'說:'+ mess.msg)
if (obj.img === '') {
var message = new Message(mess)
message.save(function (err, mess) {
if (err) {
console.log(err)
}
console.log(mess)
})
}
})
這樣就可以向對應的房間發消息啦。
核心就是在加入的時候一定要傳入房間名,否則就無法加入到某個分組中了。
###圖片上傳
1.客戶端
利用了formdata
fileup() {
var that = this
var file1 = document.getElementById('inputFile').files[0]
if (file1) {
var formdata = new window.FormData()
formdata.append('file', file1)
formdata.append('username', that.getusername)
formdata.append('src', that.getusersrc)
formdata.append('roomid', that.getuserroom)
// username: this.getusername,
// src: this.getusersrc,
this.$store.dispatch('uploadimg', formdata)
var fr = new window.FileReader()
fr.onload = function () {
var obj = {
username: that.getusername,
src: that.getusersrc,
img: fr.result,
msg: '',
room: that.getuserroom
}
console.log(obj)
that.getsocket.emit('message', obj)
}
fr.readAsDataURL(file1)
} else {
console.log('必須有文件')
}
}
2.服務器端
運用了multiparty模塊。
app.post('/file/uploadimg', function (req, res, next) {
// console.log(util.inspect(req.body, { showHidden: true, depth: null }))
// console.log(util.inspect(req.header, { showHidden: true, depth: null }))
// //生成multiparty對象,並配置上傳目標路徑
var form = new multiparty.Form()
// //設置編輯
form.encoding = 'utf-8'
// //設置文件存儲路徑
form.uploadDir = "./static/files/"
// //設置單文件大小限制
form.maxFilesSize = 2 * 1024 * 1024
// form.maxFields = 1000; 設置所以文件的大小總和
// 上傳完成後處理
form.parse(req, function (err, fields, files) {
console.log(fields)
var filesTmp = JSON.stringify(files, null, 2)
console.log(filesTmp)
if (err) {
console.log('parse error: ' + err)
res.json({
errno: 1
})
} else {
var inputFile = files.file[0];
var uploadedPath = inputFile.path
var array = inputFile.originalFilename.split('.')
var imgtype = array[array.length - 1]
var dstPath = './static/files/' + new Date().getTime() + '.' + imgtype
//重命名爲真實文件名
fs.rename(uploadedPath, dstPath, function (err) {
if (err) {
console.log('rename error: ' + err)
res.json({
errno: 1
})
} else {
var mess = {
username: fields.username,
src: fields.src,
img: dstPath,
roomid: fields.roomid
}
var message = new Message(mess)
message.save(function (err, mess) {
if (err) {
console.log(err)
}
console.log(mess)
})
console.log('rename ok')
res.json({
errno: 0
})
}
})
}
})
})
如果對於上傳有問題可以看這個axios上傳formdata失敗以及nodejs接受formdata失敗
效果圖