rtc-live.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. const {
  2. v4: uuidv4
  3. } = require("uuid")
  4. const fs = require("fs");
  5. // const server = require("http").createServer()
  6. var options = {
  7. key: fs.readFileSync('./privatekey.pem'),
  8. cert: fs.readFileSync('./certificate.pem')
  9. };
  10. const server = require("https").createServer(options)
  11. const port = 10010
  12. const one_mode_count = 2 //1V1模式只能2人
  13. const more_mode_count = 4 //多人模式只能30人
  14. const muted = false //默认开启mic
  15. const io = require("socket.io")(server, {
  16. path: "/im-rtc",
  17. serveClient: false,
  18. pingInterval: 10000,
  19. pingTimeout: 5000,
  20. cors: {
  21. origin: "*",
  22. methods: ["GET", "POST"],
  23. },
  24. })
  25. io.on("connection", socket => new ClientRequest(socket))
  26. server.listen(port)
  27. const __rooms = {}
  28. class ClientRequest {
  29. constructor(socket) {
  30. this.socket = socket
  31. this.option = socket.handshake.query
  32. this.init()
  33. // 没有roomId时新建
  34. if (!this.option.roomId) {
  35. this.option.roomId = uuidv4()
  36. }
  37. // 没有角色时默认为主持人
  38. if (!this.option.role) {
  39. this.option.role = "leader"
  40. }
  41. // 判断roomId在房间列表中是否存在
  42. if (!__rooms[this.option.roomId]) {
  43. // 初始化房间
  44. __rooms[this.option.roomId] = []
  45. }
  46. // 没有userId时新建
  47. if (!this.option.userId) {
  48. // 没有userId就新建
  49. this.option.userId = "user-" + new Date().getTime()
  50. }
  51. let {
  52. role,
  53. type,
  54. roomId,
  55. userId,
  56. userName,
  57. } = this.option
  58. let user = {
  59. role,
  60. type,
  61. roomId,
  62. userId,
  63. userName,
  64. muted
  65. }
  66. let users = __rooms[this.option.roomId]
  67. let count
  68. if (this.option.mode == '1') {
  69. count = one_mode_count
  70. } else {
  71. count = more_mode_count
  72. }
  73. if (users.length < count) {
  74. users.push(user)
  75. this.socket.join(this.option.roomId)
  76. this.socket.emit("join", {
  77. user,
  78. users,
  79. })
  80. this.onUserJoin(user, users)
  81. } else {
  82. this.socket.emit("full")
  83. }
  84. }
  85. init() {
  86. this.socket.on("disconnect", reason => this.onDisconnect(reason))
  87. this.socket.on("reconnect", reason => this.onReconnect(reason))
  88. // 通用事件
  89. this.socket.on("action", data => {
  90. this.socket.broadcast.to(this.option.roomId).emit("action", data)
  91. })
  92. this.socket.on("msg", data => {
  93. this.socket.broadcast.to(this.option.roomId).emit("msg", data)
  94. // this.socket.to(this.option.roomId).emit("msg", data)
  95. })
  96. this.socket.on("socket_changeMedia", data => {
  97. this.socket.broadcast.to(this.option.roomId).emit("socket_changeMedia", data)
  98. // io.to(this.option.roomId).emit('socket_changeMedia', data)
  99. })
  100. this.socket.on("webSyncAction", data => {
  101. console.log('webSyncAction')
  102. this.socket.broadcast.to(this.option.roomId).emit("webSyncAction", data)
  103. // io.to(this.option.roomId).emit('socket_changeMedia', data)
  104. })
  105. // 踢人
  106. this.socket.on("getOut", userId => this.onGetOut(userId))
  107. // 静音
  108. this.socket.on("muted", (muted, userId) => this.onMuted(muted, userId))
  109. // 成员关闭推流后通知静音
  110. this.socket.on("mutedChanged", (muted, userId) => io.to(this.option.roomId).emit("mutedChanged", muted, userId))
  111. }
  112. onDisconnect(reason) {
  113. let user = null
  114. let users = __rooms[this.option.roomId]
  115. for (let i = 0; i < users.length; i++) {
  116. if (this.option.userId == users[i].userId) {
  117. let splices = users.splice(i, 1)
  118. if (splices.length) {
  119. user = splices[0]
  120. }
  121. break
  122. }
  123. }
  124. user && this.onUserLeave(user, users)
  125. }
  126. onReconnect(reason) {
  127. consoel.log('重连了')
  128. }
  129. /**
  130. * 踢人
  131. */
  132. onGetOut(userId) {
  133. if (!this.isLeader()) {
  134. return
  135. }
  136. this.socket.broadcast.to(this.option.roomId).emit("getOut", userId)
  137. }
  138. /**
  139. * 静音
  140. * @param {*} muted 静音状态
  141. * @param {*} userId 如果有userId,则设置指定用户静音
  142. */
  143. onMuted(muted, userId) {
  144. // 群体静音只有主持人才能使用
  145. if (!this.isLeader()) {
  146. return
  147. }
  148. let user = null
  149. let users = __rooms[this.option.roomId]
  150. if (userId) {
  151. for (let i = 0; i < users.length; i++) {
  152. if (users[i].userId == userId) {
  153. user = users[i]
  154. user.muted = muted
  155. break
  156. }
  157. }
  158. // 没找到指定参与人时不做操作
  159. if (!user) {
  160. return
  161. }
  162. } else {
  163. // 设置所有参与人除主持人外静音状态
  164. users.forEach(item => {
  165. if (item.role == 'leader') {
  166. return
  167. }
  168. item.muted = muted
  169. });
  170. }
  171. io.to(this.option.roomId).emit("muted", muted, userId)
  172. // this.socket.broadcast.to(this.option.roomId).emit("muted", muted, userId)
  173. }
  174. /**
  175. * 通知其他用户有人加入房间
  176. */
  177. onUserJoin(user, users) {
  178. this.socket.broadcast.to(this.option.roomId).emit("userJoin", {
  179. user,
  180. users
  181. })
  182. }
  183. /**
  184. * 通知其他用户有人离开房间
  185. */
  186. onUserLeave(user, users) {
  187. this.socket.broadcast.to(this.option.roomId).emit("userLeave", {
  188. user,
  189. users
  190. })
  191. console.log(`用户[${user.userId}]离开房间`)
  192. }
  193. isLeader() {
  194. return this.option.role == "leader"
  195. }
  196. }