const { v4: uuidv4 } = require("uuid") const fs = require("fs"); const server = require("http").createServer() //本地测试用到https // var options = { // key: fs.readFileSync('./privatekey.pem'), // cert: fs.readFileSync('./certificate.pem') // }; // const server = require("https").createServer(options) const port = 10010 const one_mode_count = 2 //1V1模式只能2人 const more_mode_count = 30 //多人模式只能30人 const muted = false //默认开启mic const can_speak = true //默认开启mic const io = require("socket.io")(server, { path: "/im-rtc", serveClient: false, pingInterval: 10000, pingTimeout: 5000, cors: { origin: "*", methods: ["GET", "POST"], }, }) io.on("connection", socket => new ClientRequest(socket)) server.listen(port) const __rooms = {} class ClientRequest { constructor(socket) { this.socket = socket this.option = socket.handshake.query this.init() // 没有roomId时新建 if (!this.option.roomId) { this.option.roomId = uuidv4() } // 没有角色时默认为主持人 if (!this.option.role) { this.option.role = "leader" } // 判断roomId在房间列表中是否存在 if (!__rooms[this.option.roomId]) { // 初始化房间 __rooms[this.option.roomId] = [] } // 没有userId时新建 if (!this.option.userId) { // 没有userId就新建 this.option.userId = "user-" + new Date().getTime() } let { role, type, roomId, userId, userName, } = this.option let user = { role, type, roomId, userId, userName, muted, can_speak } let users = __rooms[this.option.roomId] let count if (this.option.mode == '1') { count = one_mode_count } else { count = more_mode_count } if (users.length < count) { users.push(user) this.socket.join(this.option.roomId) this.socket.emit("join", { user, users, }) this.onUserJoin(user, users) } else { this.socket.emit("full") } } init() { this.socket.on("disconnect", reason => this.onDisconnect(reason)) this.socket.on("reconnect", reason => this.onReconnect(reason)) // 通用事件 this.socket.on("action", data => { this.socket.broadcast.to(this.option.roomId).emit("action", data) }) this.socket.on("msg", data => { this.socket.broadcast.to(this.option.roomId).emit("msg", data) // this.socket.to(this.option.roomId).emit("msg", data) }) this.socket.on("socket_changeMedia", data => { this.socket.broadcast.to(this.option.roomId).emit("socket_changeMedia", data) // io.to(this.option.roomId).emit('socket_changeMedia', data) }) this.socket.on("webSyncAction", data => { console.log('webSyncAction') this.socket.broadcast.to(this.option.roomId).emit("webSyncAction", data) // io.to(this.option.roomId).emit('socket_changeMedia', data) }) // 踢人 this.socket.on("getOut", userId => this.onGetOut(userId)) // 静音 this.socket.on("muted", (muted, userId) => this.onMuted(muted, userId)) //禁言 this.socket.on("forbidden", (data) => { let user = null let users = __rooms[this.option.roomId] if (data.userId) { for (let i = 0; i < users.length; i++) { if (users[i].userId == data.userId) { user = users[i] user.can_speak = !data.can_speak break } } // 没找到指定参与人时不做操作 if (!user) { return } } io.to(this.option.roomId).emit("forbidden", data) // this.socket.broadcast.to(this.option.roomId).emit("forbidden", data) } ) // 成员关闭推流后通知静音 this.socket.on("mutedChanged", (muted, userId) => io.to(this.option.roomId).emit("mutedChanged", muted, userId)) } onDisconnect(reason) { let user = null let users = __rooms[this.option.roomId] for (let i = 0; i < users.length; i++) { if (this.option.userId == users[i].userId) { let splices = users.splice(i, 1) if (splices.length) { user = splices[0] } break } } user && this.onUserLeave(user, users) } onReconnect(reason) { consoel.log('重连了') } /** * 踢人 */ onGetOut(userId) { if (!this.isLeader()) { return } this.socket.broadcast.to(this.option.roomId).emit("getOut", userId) } /** * 静音 * @param {*} muted 静音状态 * @param {*} userId 如果有userId,则设置指定用户静音 */ onMuted(muted, userId) { // 群体静音只有主持人才能使用 if (!this.isLeader()) { return } let user = null let users = __rooms[this.option.roomId] if (userId) { for (let i = 0; i < users.length; i++) { if (users[i].userId == userId) { user = users[i] user.muted = muted break } } // 没找到指定参与人时不做操作 if (!user) { return } } else { // 设置所有参与人除主持人外静音状态 users.forEach(item => { if (item.role == 'leader') { return } item.muted = muted }); } io.to(this.option.roomId).emit("muted", muted, userId) // this.socket.broadcast.to(this.option.roomId).emit("muted", muted, userId) } /** * 通知其他用户有人加入房间 */ onUserJoin(user, users) { this.socket.broadcast.to(this.option.roomId).emit("userJoin", { user, users }) } /** * 通知其他用户有人离开房间 */ onUserLeave(user, users) { this.socket.broadcast.to(this.option.roomId).emit("userLeave", { user, users }) console.log(`用户[${user.userId}]离开房间`) } isLeader() { return this.option.role == "leader" } }