250 lines
8.6 KiB
JavaScript
250 lines
8.6 KiB
JavaScript
/*
|
||
*介绍:socket.io 功能封装
|
||
*作者:TaiGuangYin
|
||
*时间:2017-09-09
|
||
* */
|
||
var redis = require('../utils/redis');
|
||
var msgType = require('./messageTpye');
|
||
var ioSvc = require('./ioHelper').ioSvc;
|
||
var AppConfig = require('../config');
|
||
var Common = require('../utils/common');
|
||
var msgModel = require('../model/message');
|
||
const sessoionModel = require('../model/session');
|
||
const userModel = require('./../model/users');
|
||
|
||
//服务端连接
|
||
function ioServer(io) {
|
||
|
||
var _self = this;
|
||
ioSvc.setInstance(io);
|
||
|
||
var __uuids = [];
|
||
|
||
//初始化连接人数
|
||
// redis.set('online_count', 0, null, function (err, ret) {
|
||
// if (err) {
|
||
// console.error(err);
|
||
// }
|
||
// });
|
||
|
||
Array.prototype.remove = function (val) {
|
||
var index = this.indexOf(val);
|
||
if (index > -1) {
|
||
this.splice(index, 1);
|
||
}
|
||
};
|
||
|
||
io.on('connection', async function (socket) {
|
||
console.log('有新的连接进来了:', socket.id);
|
||
|
||
//用户与Socket进行绑定
|
||
socket.on('login', async function (msg) {
|
||
var uid = msg.uid;
|
||
socket._user = msg;
|
||
let type = msg.type; // 获取用户类型
|
||
console.log(type, uid, '登录成功');
|
||
|
||
//如果不是客服登录
|
||
if (type != 'kefu') {
|
||
let gongHao = msg.kefu_id;
|
||
let location = Common.getIpLocation(msg.ip);
|
||
// 获取管理员的socket
|
||
try {
|
||
//获取管理员 socket
|
||
let kefuData = await sessoionModel.find(gongHao,null);
|
||
if (kefuData) { // 找到客服数据
|
||
console.log('来自', location, '的客户连接,处理客服 gongHao=>', gongHao)
|
||
// let socket = socket.id;
|
||
// let type = 'customer';
|
||
// let kefu_id = gongHao;
|
||
|
||
let clientInfo = {
|
||
uid,
|
||
nickname: location + ' 客户',
|
||
type: 'online',
|
||
status: 1,
|
||
};
|
||
// 添加客户到 对应的客服
|
||
await sessoionModel.createOrUpdate({uid}, (isCreate) => {
|
||
console.log('is new ',isCreate);
|
||
let data = {
|
||
uid,
|
||
socket: socket.id,
|
||
kefu_id: gongHao,
|
||
status: 1
|
||
};
|
||
if (isCreate) {
|
||
data['type'] = 'customer';
|
||
data['nickname'] = clientInfo.nickname;
|
||
}
|
||
return data;
|
||
})
|
||
socket.emit('connect-success',{
|
||
nickname:kefuData.nickname,
|
||
socket:kefuData.socket,
|
||
status:kefuData.status
|
||
});
|
||
// 给管理员发送通知
|
||
io.to(kefuData.socket).emit('update-users', clientInfo);
|
||
}else{
|
||
socket.emit('log','暂无客服可用,请使用其他方式联系!')
|
||
}
|
||
} catch (e) {
|
||
//TODO 失败重发机制
|
||
console.log('给管理员发送通知失败', e);
|
||
}
|
||
|
||
}
|
||
else {
|
||
try {
|
||
let kefu = await userModel.findByUserName(uid);
|
||
// 保存客服socket
|
||
sessoionModel.createOrUpdate({uid}, {
|
||
uid,
|
||
socket: socket.id,
|
||
type: 'kefu',
|
||
nickname: kefu.nickname,
|
||
status: 1
|
||
})
|
||
|
||
try{
|
||
let sessList = await sessoionModel.findByCondition({status:1,kefu_id:uid});
|
||
|
||
sessList.forEach(s => {
|
||
io.to(s.socket).emit('connect-success',{
|
||
nickname:kefu.nickname,
|
||
socket:socket.id,
|
||
status:1
|
||
});
|
||
// io.to(s.socket).emit('kefu-logout', user);
|
||
});
|
||
}catch(e){
|
||
|
||
}
|
||
} catch (e) {
|
||
console.log('客服 ' + uid + ' 登录失败了', e);
|
||
}
|
||
}
|
||
});
|
||
|
||
//断开事件
|
||
socket.on('disconnect', async function () {
|
||
// _self.updateOnlineCount(false);
|
||
let user = socket['_user'];
|
||
if (user) {
|
||
// 更新用户状态
|
||
await sessoionModel.update(user.uid, {status: 0});
|
||
console.log("用户已经中断了连接",user);
|
||
if(user.type == 'kefu'){
|
||
// 将所有的客服服务对象下线
|
||
try{
|
||
let sessList = await sessoionModel.findByCondition({status:1,kefu_id:user.uid});
|
||
|
||
sessList.forEach(s => {
|
||
io.to(s.socket).emit('kefu-logout', user);
|
||
});
|
||
}catch(e){
|
||
|
||
}
|
||
return;
|
||
}
|
||
if (user.type == 'customer' && user.kefu_id) {
|
||
// 查找对应kf通知下线操作
|
||
let kf_data = await sessoionModel.find(user.kefu_id);
|
||
|
||
if (kf_data && kf_data.status == 1) { // 客服在线才通知哟
|
||
let info = {
|
||
"uid":user.uid,
|
||
"type": 'offline',
|
||
"nickname":"",
|
||
status: 0
|
||
};
|
||
io.to(kf_data.socket).emit('update-users', info);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
});
|
||
|
||
//重连事件
|
||
socket.on('reconnect', function () {
|
||
console.log("重新连接到服务器");
|
||
});
|
||
|
||
//监听客户端发送的信息,实现消息转发到各个其他客户端
|
||
socket.on('message', async function (msg) {
|
||
let userData = socket['_user'];
|
||
if (!userData) {
|
||
return;
|
||
}
|
||
//保存消息到数据库
|
||
msgModel.add(msg.from_uid, msg.uid, msg.content, msg.chat_type, msg.image, function (err) {
|
||
if (err) {
|
||
console.error(err);
|
||
}
|
||
});
|
||
const sendMsg = {
|
||
"uid": msg.from_uid,
|
||
"content": msg.content,
|
||
"chat_type": msg.chat_type ? msg.chat_type : 'text',
|
||
"image": msg.image
|
||
};
|
||
if (msg.type == msgType.messageType.public) { // 广播
|
||
socket.broadcast.emit("message", sendMsg);
|
||
} else if (msg.type == msgType.messageType.private) {
|
||
let uid = msg.uid; // 对方uid
|
||
console.log('find kefu data', msg)
|
||
// 暂时不 await
|
||
sessoionModel.find(uid).then(toUser => {
|
||
console.log('find kefu data', toUser)
|
||
if (toUser && toUser.status == 1) { // 对方在线才发送消息哟
|
||
io.to(toUser.socket).emit('message', sendMsg);
|
||
}
|
||
}).catch(e => {
|
||
console.log('find kefu data exception', e)
|
||
});
|
||
|
||
}
|
||
|
||
});
|
||
});
|
||
|
||
this.updateOnlineCount = function (isConnect) {
|
||
return;
|
||
// 更新在线客户连接数
|
||
redis.get('online_count', function (err, val) {
|
||
if (err) {
|
||
console.error(err);
|
||
}
|
||
if (!val) {
|
||
val = 0;
|
||
}
|
||
if (typeof val == 'string') {
|
||
val = parseInt(val);
|
||
}
|
||
if (isConnect) {
|
||
val += 1;
|
||
} else {
|
||
val -= 1;
|
||
if (val <= 0) {
|
||
val = 0;
|
||
}
|
||
}
|
||
|
||
console.log('当前在线人数:' + val);
|
||
io.sockets.emit('update_online_count', {online_count: val});
|
||
|
||
redis.set('online_count', val, null, function (err, ret) {
|
||
if (err) {
|
||
console.error(err);
|
||
}
|
||
});
|
||
});
|
||
};
|
||
|
||
}
|
||
|
||
|
||
//模块导出
|
||
exports.ioServer = ioServer; |