You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.8 KiB
JavaScript
127 lines
3.8 KiB
JavaScript
const io = require('socket.io')({
|
|
cors: {
|
|
origin: '*',
|
|
allowedHeaders: ["my-custom-header"],
|
|
credentials: true,
|
|
},
|
|
serveClient:false
|
|
});
|
|
const jwt=require("./jwt");
|
|
const store=require("./store");
|
|
const util={
|
|
async login(user,socket,isReconnect) {
|
|
let ip=socket.handshake.address.replace(/::ffff:/,"");
|
|
const headers = socket.handshake.headers;
|
|
const realIP = headers['x-forwarded-for'];
|
|
ip=realIP?realIP:ip;
|
|
const deviceType=this.getDeviceType(socket.handshake.headers["user-agent"].toLowerCase());
|
|
user.ip=ip;
|
|
user.deviceType=deviceType;
|
|
user.roomId=socket.id;
|
|
user.type='user';
|
|
if(isReconnect){
|
|
this.loginSuccess(user,socket);
|
|
console.log(`用户<${user.name}>重新链接成功!`)
|
|
}else {
|
|
const flag=await this.isHaveName(user.name);
|
|
if(!flag){
|
|
user.id=socket.id;
|
|
user.time=new Date().getTime();
|
|
this.loginSuccess(user,socket);
|
|
store.saveUser(user,'login')
|
|
const messages = await store.getMessages();
|
|
socket.emit("history-message","group_001",messages);
|
|
}else {
|
|
console.log(`登录失败,昵称<${user.name}>已存在!`)
|
|
socket.emit('loginFail','登录失败,昵称已存在!')
|
|
}
|
|
}
|
|
},
|
|
async loginSuccess(user, socket) {
|
|
const data={
|
|
user:user,
|
|
token:jwt.token(user)
|
|
};
|
|
socket.broadcast.emit('system', user, 'join');
|
|
socket.on('message',(from, to,message,type)=> {
|
|
if(to.type==='user'){
|
|
socket.broadcast.to(to.roomId).emit('message', socket.user, to,message,type);
|
|
}
|
|
if(to.type==='group'){
|
|
socket.broadcast.emit('message', socket.user,to,message,type);
|
|
store.saveMessage(from,to,message,type)
|
|
}
|
|
});
|
|
const users=await this.getOnlineUsers();
|
|
socket.user=user;
|
|
socket.emit('loginSuccess', data, users);
|
|
},
|
|
//根据useragent判读设备类型
|
|
getDeviceType(userAgent){
|
|
let bIsIpad = userAgent.match(/ipad/i) == "ipad";
|
|
let bIsIphoneOs = userAgent.match(/iphone os/i) == "iphone os";
|
|
let bIsMidp = userAgent.match(/midp/i) == "midp";
|
|
let bIsUc7 = userAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
|
|
let bIsUc = userAgent.match(/ucweb/i) == "ucweb";
|
|
let bIsAndroid = userAgent.match(/android/i) == "android";
|
|
let bIsCE = userAgent.match(/windows ce/i) == "windows ce";
|
|
let bIsWM = userAgent.match(/windows mobile/i) == "windows mobile";
|
|
if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) {
|
|
return "phone";
|
|
} else {
|
|
return "pc";
|
|
}
|
|
},
|
|
//获取在线用户列表
|
|
async getOnlineUsers(){
|
|
const users=[
|
|
{
|
|
id:"group_001",
|
|
name:"群聊天室",
|
|
avatarUrl:"static/img/avatar/group-icon.png",
|
|
type:"group"
|
|
}
|
|
];
|
|
const clients=await io.fetchSockets();
|
|
clients.forEach((item) => {
|
|
if(item.user){
|
|
users.push(item.user)
|
|
}
|
|
})
|
|
return users;
|
|
},
|
|
//判断用户是否已经存在
|
|
async isHaveName(name){
|
|
const users=await this.getOnlineUsers();
|
|
return users.some(item => item.name===name)
|
|
},
|
|
};
|
|
io.sockets.on('connection',(socket)=>{
|
|
const token=socket.handshake.headers.token;
|
|
let decode=null;
|
|
if(token){
|
|
decode=jwt.decode(token);
|
|
}
|
|
let user=decode?decode.data:{};
|
|
socket.on("disconnect",(reason)=>{
|
|
//判断是否是已登录用户
|
|
if (socket.user&&socket.user.id) {
|
|
//删除登录用户信息,并通知所有在线用户
|
|
socket.broadcast.emit('system', socket.user, 'logout');
|
|
store.saveUser(socket.user,'logout')
|
|
}
|
|
console.log(reason)
|
|
});
|
|
//判断链接用户是否已经登录
|
|
if(user&&user.id){
|
|
//已登录的用户重新登录
|
|
util.login(user,socket,true);
|
|
}else {
|
|
//监听用户登录事件
|
|
socket.on('login',(user)=>{
|
|
util.login(user,socket,false)
|
|
});
|
|
}
|
|
});
|
|
module.exports=io;
|