mirror of
https://github.com/darkwire/darkwire.io.git
synced 2025-07-19 19:14:53 +00:00
162 lines
3.5 KiB
JavaScript
162 lines
3.5 KiB
JavaScript
import _ from 'lodash';
|
|
import uuid from 'uuid/v4';
|
|
import { getIO, getRedis } from './index'
|
|
|
|
export default class Socket {
|
|
constructor(opts) {
|
|
const { roomId, socket, room, roomIdOriginal } = opts
|
|
|
|
this._roomId = roomId
|
|
this.socket = socket;
|
|
this.roomIdOriginal = roomIdOriginal;
|
|
this.room = room;
|
|
if (room.isLocked) {
|
|
this.sendRoomLocked();
|
|
return
|
|
}
|
|
|
|
this.init(opts)
|
|
}
|
|
|
|
async init(opts) {
|
|
const { roomId, socket, room } = opts
|
|
await this.joinRoom(roomId, socket.id)
|
|
this.sendRoomInfo();
|
|
this.handleSocket(socket)
|
|
}
|
|
|
|
sendRoomInfo() {
|
|
let room;
|
|
if (_.isEmpty(this.room)) {
|
|
room = {
|
|
id: this.roomIdOriginal,
|
|
users: [],
|
|
isLocked: false,
|
|
}
|
|
} else {
|
|
room = this.room;
|
|
}
|
|
this.socket.emit('CONNECTED', room);
|
|
}
|
|
|
|
sendRoomLocked() {
|
|
this.socket.emit('ROOM_LOCKED');
|
|
}
|
|
|
|
async saveRoom(room) {
|
|
const json = {
|
|
...room,
|
|
updatedAt: Date.now(),
|
|
}
|
|
|
|
return getRedis().hsetAsync('rooms', this._roomId, JSON.stringify(json))
|
|
}
|
|
|
|
async destroyRoom() {
|
|
return getRedis().hdel('rooms', this._roomId)
|
|
}
|
|
|
|
fetchRoom() {
|
|
return new Promise(async (resolve, reject) => {
|
|
const res = await getRedis().hgetAsync('rooms', this._roomId)
|
|
resolve(JSON.parse(res || '{}'))
|
|
})
|
|
}
|
|
|
|
joinRoom(roomId, socketId) {
|
|
return new Promise((resolve, reject) => {
|
|
getIO().of('/').adapter.remoteJoin(socketId, roomId, (err) => {
|
|
if (err) {
|
|
reject()
|
|
}
|
|
resolve()
|
|
});
|
|
});
|
|
}
|
|
|
|
async handleSocket(socket) {
|
|
socket.on('PAYLOAD', (payload) => {
|
|
socket.to(this._roomId).emit('PAYLOAD', payload);
|
|
});
|
|
|
|
socket.on('USER_ENTER', async payload => {
|
|
let room = await this.fetchRoom()
|
|
if (_.isEmpty(room)) {
|
|
room = {
|
|
id: this._roomId,
|
|
users: [],
|
|
isLocked: false,
|
|
createdAt: Date.now(),
|
|
}
|
|
}
|
|
|
|
const newRoom = {
|
|
...room,
|
|
users: [...(room.users || []), {
|
|
socketId: socket.id,
|
|
publicKey: payload.publicKey,
|
|
isOwner: (room.users || []).length === 0,
|
|
}]
|
|
}
|
|
await this.saveRoom(newRoom)
|
|
getIO().to(this._roomId).emit('USER_ENTER', newRoom.users.map(u => ({
|
|
publicKey: u.publicKey,
|
|
isOwner: u.isOwner,
|
|
})));
|
|
})
|
|
|
|
socket.on('TOGGLE_LOCK_ROOM', async (data, callback) => {
|
|
const room = await this.fetchRoom()
|
|
const user = (room.users || []).find(u => u.socketId === socket.id && u.isOwner)
|
|
|
|
if (!user) {
|
|
callback({
|
|
isLocked: room.isLocked,
|
|
})
|
|
return
|
|
}
|
|
|
|
await this.saveRoom({
|
|
...room,
|
|
isLocked: !room.isLocked,
|
|
})
|
|
|
|
socket.to(this._roomId).emit('TOGGLE_LOCK_ROOM', {
|
|
locked: !room.isLocked,
|
|
publicKey: user && user.publicKey
|
|
});
|
|
|
|
callback({
|
|
isLocked: !room.isLocked,
|
|
})
|
|
});
|
|
|
|
socket.on('disconnect', () => this.handleDisconnect(socket));
|
|
|
|
socket.on('USER_DISCONNECT', () => this.handleDisconnect(socket));
|
|
}
|
|
|
|
async handleDisconnect(socket) {
|
|
let room = await this.fetchRoom()
|
|
|
|
const newRoom = {
|
|
...room,
|
|
users: (room.users || []).filter(u => u.socketId !== socket.id).map((u, index) => ({
|
|
...u,
|
|
isOwner: index === 0,
|
|
}))
|
|
}
|
|
|
|
await this.saveRoom(newRoom)
|
|
|
|
getIO().to(this._roomId).emit('USER_EXIT', newRoom.users);
|
|
|
|
if (newRoom.users && newRoom.users.length === 0) {
|
|
await this.destroyRoom()
|
|
}
|
|
|
|
socket.disconnect(true);
|
|
}
|
|
|
|
}
|