socketv2.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. var server = require("http").createServer();
  2. const EVENT = {
  3. someOneInRoom: 'someOneInRoom',
  4. someOneLeaveRoom: 'someOneLeaveRoom',
  5. startCall: 'startCall',
  6. stopCall: 'stopCall',
  7. webSyncAction: 'webSyncAction',
  8. clientSyncAction: 'clientSyncAction',
  9. action: 'action',
  10. roomClose: 'roomClose',
  11. roomIn: 'roomIn',
  12. changeVoiceStatus: 'changeVoiceStatus'
  13. }
  14. module.exports = class WebSocketServer {
  15. constructor() {
  16. this._pageMap = new Map();
  17. this._roomIDS = new Map();
  18. this._roomPerson = new Map()
  19. }
  20. create() {
  21. this.io = require("socket.io")(server, {
  22. path: "/vr-node",
  23. serveClient: false,
  24. // below are engine.IO options
  25. pingInterval: 10000,
  26. pingTimeout: 5000,
  27. cookie: false,
  28. });
  29. server.listen(3030, { origins: "*" });
  30. this.io.on("connection", (socket) => {
  31. let user = socket.handshake.query
  32. const { roomId, userId, sceneNum, isClient, role, userLimitNum } = user
  33. const webRoomId = `${roomId}_web`
  34. const clientRoom = userId ? `${userId}` : `${userId}${roomId}`
  35. // 加入客户端与H5单独的通讯房间
  36. socket.join(clientRoom, () => {
  37. console.log('join success', clientRoom, user)
  38. })
  39. socket.on(EVENT.clientSyncAction, (data) => {
  40. console.log('client', clientRoom, data)
  41. socket.broadcast.to(clientRoom).emit(EVENT.clientSyncAction, data)
  42. })
  43. socket.on(EVENT.changeVoiceStatus, data => {
  44. let _roomPerson = this._roomPerson.get(roomId) || []
  45. user.voiceStatus = data.status
  46. console.log(_roomPerson, '_roomPerson')
  47. _roomPerson.forEach(item => {
  48. if (item.userId === user.userId) {
  49. item.voiceStatus = user.voiceStatus
  50. }
  51. })
  52. this._roomPerson.set(roomId, _roomPerson)
  53. socket.broadcast.to(roomId).emit(EVENT.changeVoiceStatus, {roomsPerson: sortRoomUser(_roomPerson)})
  54. })
  55. // 若有房间人数限制
  56. if (userLimitNum && this._roomPerson.get(roomId) && sortRoomUser(this._roomPerson.get(roomId)).length >= userLimitNum) {
  57. console.log(this._roomPerson.get(roomId), 'full')
  58. console.log(this._roomPerson.get(roomId).length, userLimitNum, 'full')
  59. setTimeout(() => {
  60. socket.emit('roomInFail', { type: 'full', msg: '房间人数已满' })
  61. }, 1000)
  62. return this
  63. }
  64. // 若已结束、房间已关闭
  65. if ( user.role !== 'leader'&& ((this._roomPerson.get(roomId) && !this._roomPerson.get(roomId).find(item => item.role === 'leader')) || (!this._roomPerson.get(roomId)))) {
  66. console.log('roomClose')
  67. setTimeout(() => {
  68. socket.emit(EVENT.roomClose)
  69. }, 1000)
  70. return this
  71. }
  72. // 加入所有连接数的通讯房间
  73. socket.join(roomId, () => {
  74. // 只有h5才能加入H5端的房间
  75. if (!isClient) {
  76. let roomsPerson = this._roomPerson.get(roomId) || []
  77. roomsPerson.push(user)
  78. this._roomPerson.set(roomId, roomsPerson)
  79. }
  80. })
  81. let clientPerson = this._roomPerson.get(clientRoom) || []
  82. if (isClient) {
  83. clientPerson.push(user)
  84. this._roomPerson.set(clientRoom, clientPerson)
  85. } else {
  86. clientPerson.forEach(item => {
  87. if (item.userId === user.userId) {
  88. user.avatar = item.avatar
  89. user.voiceStatus = item.voiceStatus
  90. }
  91. })
  92. }
  93. socket.on(EVENT.startCall, () => {
  94. console.log('startcall', user)
  95. if (!isClient) {
  96. socket.join(webRoomId, () => {
  97. console.log('join webRoom', user)
  98. let roomsPerson = this._roomPerson.get(roomId) || []
  99. socket.emit(EVENT.roomIn, { roomsPerson: sortRoomUser(roomsPerson) })
  100. socket.broadcast.to(roomId).emit(EVENT.someOneInRoom, { user, roomsPerson: sortRoomUser(roomsPerson) })
  101. })
  102. }
  103. })
  104. socket.on(EVENT.stopCall, () => {
  105. console.log('stopCall', user)
  106. socket.leave(roomId)
  107. if (role === 'leader') {
  108. socket.broadcast.to(roomId).emit(EVENT.roomClose)
  109. }
  110. if (!isClient) {
  111. socket.leave(webRoomId)
  112. let roomsPerson = this._roomPerson.get(roomId) || []
  113. roomsPerson = removeRoomUser(roomsPerson, user)
  114. this._roomPerson.set(roomId, roomsPerson)
  115. socket.broadcast.to(roomId).emit(EVENT.someOneLeaveRoom, { user, roomsPerson: sortRoomUser(roomsPerson) })
  116. }
  117. })
  118. socket.on(EVENT.webSyncAction, (data) => {
  119. socket.broadcast.to(webRoomId).emit(EVENT.webSyncAction, data)
  120. })
  121. socket.on(EVENT.action, (data) => {
  122. socket.broadcast.to(roomId).emit(EVENT.action, data)
  123. })
  124. socket.on("disconnect", (reason) => {
  125. console.log(reason, 'reason')
  126. socket.leave(roomId)
  127. if (!isClient) {
  128. // if (role === 'leader' && reason !== 'ping timeout') {
  129. // socket.broadcast.to(roomId).emit(EVENT.roomClose)
  130. // }
  131. let roomsPerson = this._roomPerson.get(roomId) || []
  132. roomsPerson = removeRoomUser(roomsPerson, user)
  133. this._roomPerson.set(roomId, roomsPerson)
  134. // socket.broadcast.to(roomId).emit(EVENT.someOneLeaveRoom, { user, roomsPerson })
  135. socket.leave(webRoomId)
  136. socket.leave(roomId)
  137. }
  138. })
  139. socket.on('reconnect', () => {
  140. console.log('重连', user)
  141. socket.join(roomId)
  142. if (!isClient) {
  143. let roomsPerson = this._roomPerson.get(roomId) || []
  144. roomsPerson.push(user)
  145. this._roomPerson.set(roomId, roomsPerson)
  146. socket.join(webRoomId)
  147. socket.join(roomId)
  148. }
  149. })
  150. socket.on("error", function (reason) {
  151. console.log("异常关闭", reason)
  152. })
  153. return this;
  154. })
  155. }
  156. close() {
  157. this.server.disconnect(true);
  158. }
  159. };
  160. function removeRoomUser (roomsPerson, user) {
  161. for (let i = 0; i < roomsPerson.length; i++) {
  162. if (roomsPerson[i].userId === user.userId) {
  163. roomsPerson.splice(i, 1)
  164. }
  165. }
  166. return roomsPerson
  167. }
  168. function sortRoomUser (roomsPerson) {
  169. const res = new Map()
  170. return roomsPerson.filter((a) => !res.has(a.userId) && res.set(a.userId, 1))
  171. }