socketv2.js 6.3 KB

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