socket.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /**
  2. * socket入口脚本文件
  3. *
  4. * @author caiaolin
  5. * @date 2017-05-12
  6. * @version
  7. */
  8. import socket from "socket.io";
  9. const { PageTarget } = require('./public/common_constants');
  10. const socketIO = socket(3300);
  11. const userCache = {};
  12. function getEditingUsers(projectID) {
  13. const users = userCache[projectID];
  14. if (!users) {
  15. return [];
  16. }
  17. const rst = [];
  18. const existMap = {};
  19. for (const user of users) {
  20. if (existMap[user._id]) {
  21. continue;
  22. }
  23. existMap[user._id] = true;
  24. rst.push(user);
  25. }
  26. return rst;
  27. }
  28. // socket.io相关操作
  29. socketIO.on('connection', function(socket) {
  30. let roomInfo = {};
  31. let curUser;
  32. let curProjectID;
  33. console.log("new connection");
  34. // 加入房间
  35. socket.on('join', function(data) {
  36. const { roomData, payload } = data;
  37. if (payload && payload.user) {
  38. curUser = payload.user;
  39. }
  40. if (roomData) {
  41. if (roomData.projectID) {
  42. curProjectID = roomData.projectID;
  43. if (!userCache[roomData.projectID]) {
  44. userCache[roomData.projectID] = [];
  45. }
  46. // 由于用户可以重复打开项目,因此不做唯一性处理
  47. userCache[roomData.projectID].push(curUser);
  48. }
  49. for(let key in roomData){
  50. roomInfo[key] = roomData[key];
  51. socket.join(roomData[key], () => {
  52. if (key === 'projectID') {
  53. const editingUsers = getEditingUsers(curProjectID);
  54. if (editingUsers.length > 1) { // 只有一个用户数据,说明只有用户自己打开项目,不需要推送数据,减少触发。
  55. socket.broadcast.to(roomInfo.projectID).emit('handleAvatarList', {editingUsers});
  56. socket.emit('handleAvatarList', {editingUsers});
  57. }
  58. }
  59. });
  60. }
  61. }
  62. });
  63. // 数据更改通知
  64. socket.on('unitFileChangeNotify', function(data) {
  65. socket.broadcast.to(roomInfo['unitFile']).emit('unitFileChange', data);
  66. if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
  67. });
  68. socket.on('feeRateChangeNotify', function(data) {
  69. socket.broadcast.to(roomInfo['feeRate']).emit('feeRateChange', data);
  70. if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
  71. });
  72. socket.on('changeNewRoom', function(data) {
  73. if(data.projectID){//如果有项目ID,则通知同一个项目在其它地方被打开的页面
  74. socket.broadcast.to(data.oldRoom).emit('changeFileNotify', data);
  75. if(data.userID) socket.broadcast.to(data.userID).emit('fileDataChange', data);
  76. }
  77. socket.leave(data.oldRoom);
  78. socket.join(data.newRoom);
  79. roomInfo[data.name]=data.newRoom;
  80. });
  81. socket.on('removeProjectMark', function(data) {
  82. if(data.projectID && data.userID){
  83. socket.broadcast.to(data.userID).emit('refreshProjectIcon', data);
  84. }
  85. });
  86. socket.on('multiFileChangeNotify', function(data) {
  87. console.log(data);
  88. let projectID = data.projects[0].projectID;
  89. let userID = data.user_id;
  90. if(projectID && userID){//通知项目管理页面
  91. socket.broadcast.to(userID).emit('fileDataChange', {projectID:projectID});
  92. }
  93. for(let fileID of data.oldFileIDs){//通知已打开的项目页面
  94. let messageTitle = data.from == "feeRateFile"?"feeRateChange":"unitFileChange";
  95. socket.broadcast.to(fileID).emit(messageTitle, data);
  96. }
  97. });
  98. // 分享权限变更
  99. socket.on('sharePermissionChange', function ({ permissionType, userID, compilationID, projectID }) {
  100. // 推送给项目管理页面
  101. socket.broadcast.to(`${userID}@${compilationID}`).emit('sharePermissionChange', { permissionType, target: PageTarget.PM, payload: { projectID } });
  102. // 推送给主页面
  103. socket.broadcast.to(`${userID}@${projectID}`).emit('sharePermissionChange', { permissionType, target: PageTarget.MAIN });
  104. });
  105. socket.on('disconnect', function () {
  106. // 由于用户可以重复打开项目,因此不做唯一性处理,只删除一个数据,不删除所有的同用户数据
  107. if (curProjectID && userCache[curProjectID]) {
  108. const index = userCache[curProjectID].findIndex(user => user._id === curUser._id);
  109. if (index >= 0) {
  110. userCache[curProjectID].splice(index, 1);
  111. if (!userCache[curProjectID].length) {
  112. delete userCache[curProjectID];
  113. }
  114. const editingUsers = getEditingUsers(curProjectID);
  115. socket.broadcast.to(roomInfo.projectID).emit('handleAvatarList', {editingUsers});
  116. socket.emit('handleAvatarList', {editingUsers});
  117. }
  118. }
  119. console.log("client disconnect =========="+JSON.stringify(roomInfo));
  120. });
  121. });