rtc-live.js 6.9 KB

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