/** * socket入口脚本文件 * * @author caiaolin * @date 2017-05-12 * @version */ import socket from "socket.io"; const socketIO = socket(3300); const userCache = {}; function getEditingUsers(projectID) { const users = userCache[projectID]; if (!users) { return []; } const rst = []; const existMap = {}; for (const user of users) { if (existMap[user._id]) { continue; } existMap[user._id] = true; rst.push(user); } return rst; } // socket.io相关操作 socketIO.on('connection', function(socket) { let roomInfo = {}; let curUser; let curProjectID; console.log("new connection"); // 加入房间 socket.on('join', function(data) { const { roomData, payload } = data; if (payload && payload.user) { curUser = payload.user; } if (roomData) { if (roomData.projectID) { curProjectID = roomData.projectID; if (!userCache[roomData.projectID]) { userCache[roomData.projectID] = []; } // 由于用户可以重复打开项目,因此不做唯一性处理 userCache[roomData.projectID].push(curUser); } for(let key in roomData){ roomInfo[key] = roomData[key]; socket.join(roomData[key], () => { if (key === 'projectID') { const editingUsers = getEditingUsers(curProjectID); if (editingUsers.length > 1) { // 只有一个用户数据,说明只有用户自己打开项目,不需要推送数据,减少触发。 socket.broadcast.to(roomInfo.projectID).emit('handleAvatarList', {editingUsers}); socket.emit('handleAvatarList', {editingUsers}); } } }); } } }); // 数据更改通知 socket.on('unitFileChangeNotify', function(data) { socket.broadcast.to(roomInfo['unitFile']).emit('unitFileChange', data); if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data); }); socket.on('feeRateChangeNotify', function(data) { socket.broadcast.to(roomInfo['feeRate']).emit('feeRateChange', data); if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data); }); socket.on('changeNewRoom', function(data) { if(data.projectID){//如果有项目ID,则通知同一个项目在其它地方被打开的页面 socket.broadcast.to(data.oldRoom).emit('changeFileNotify', data); if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data); } socket.leave(data.oldRoom); socket.join(data.newRoom); roomInfo[data.name]=data.newRoom; }); socket.on('removeProjectMark', function(data) { if(data.projectID && data.userID){ socket.broadcast.to(data.userID).emit('refreshProjectIcon', data); } }); socket.on('multiFileChangeNotify', function(data) { console.log(data); let projectID = data.projects[0].projectID; let userID = data.user_id; if(projectID && userID){//通知项目管理页面 socket.broadcast.to(userID).emit('fileDataChange', {projectID:projectID}); } for(let fileID of data.oldFileIDs){//通知已打开的项目页面 let messageTitle = data.from == "feeRateFile"?"feeRateChange":"unitFileChange"; socket.broadcast.to(fileID).emit(messageTitle, data); } }); socket.on('disconnect', function () { // 由于用户可以重复打开项目,因此不做唯一性处理,只删除一个数据,不删除所有的同用户数据 if (curProjectID && userCache[curProjectID]) { const index = userCache[curProjectID].findIndex(user => user._id === curUser._id); if (index >= 0) { userCache[curProjectID].splice(index, 1); if (!userCache[curProjectID].length) { delete userCache[curProjectID]; } const editingUsers = getEditingUsers(curProjectID); socket.broadcast.to(roomInfo.projectID).emit('handleAvatarList', {editingUsers}); socket.emit('handleAvatarList', {editingUsers}); } } console.log("client disconnect =========="+JSON.stringify(roomInfo)); }); });