parent
							
								
									248e65db47
								
							
						
					
					
						commit
						ddeaca06c2
					
				@ -1,20 +0,0 @@ | 
				
			||||
import express from "express"; | 
				
			||||
import socketIO from "socket.io"; | 
				
			||||
 | 
				
			||||
const PORT = 3001; | 
				
			||||
 | 
				
			||||
const app = express(); | 
				
			||||
 | 
				
			||||
app.get('/', (req, res) => res.send('Hello World!')); | 
				
			||||
 | 
				
			||||
const server = app.listen(PORT, () => console.log(`Example app listening on port ${PORT}!`)); | 
				
			||||
const io = socketIO(server); | 
				
			||||
 | 
				
			||||
io.on('connection', socket => { | 
				
			||||
    console.log('a user connected', socket.id); | 
				
			||||
 | 
				
			||||
    setInterval(() => { | 
				
			||||
        console.log('send :)') | 
				
			||||
        socket.emit("SENDING_NEW_TIME", "ASD") | 
				
			||||
    }, 1500) | 
				
			||||
}); | 
				
			||||
@ -0,0 +1,109 @@ | 
				
			||||
const User = require("./User.js"); | 
				
			||||
 | 
				
			||||
module.exports = class Lobby { | 
				
			||||
    /** | 
				
			||||
     * @type {User[]} | 
				
			||||
     */ | 
				
			||||
    users = []; | 
				
			||||
    /** | 
				
			||||
     * @type {string|undefined} | 
				
			||||
     */ | 
				
			||||
    leaderId = undefined; | 
				
			||||
 | 
				
			||||
    running = false; | 
				
			||||
    runningInterval = undefined; | 
				
			||||
    currentTime = 0; | 
				
			||||
 | 
				
			||||
    constructor(name) { | 
				
			||||
        this.name = name; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    run() { | 
				
			||||
        this.running = true; | 
				
			||||
        this.runningInterval = setInterval(() => { | 
				
			||||
            this.currentTime += 1; | 
				
			||||
        }, 1000); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    pause() { | 
				
			||||
        this.running = false; | 
				
			||||
        clearInterval(this.runningInterval); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @returns {boolean} | 
				
			||||
     */ | 
				
			||||
    hasUsers() { | 
				
			||||
        return this.users.length !== 0; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    setRandomLeader() { | 
				
			||||
        if (this.hasUsers()) { | 
				
			||||
            this.leaderId = this.users[0].id; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @param {User} user | 
				
			||||
     */ | 
				
			||||
    addUser(user) { | 
				
			||||
        this.users.push(user); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @param id | 
				
			||||
     * @returns {User|undefined} | 
				
			||||
     */ | 
				
			||||
    getUser(id) { | 
				
			||||
        return this.users.find(u => u.id === id); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @param {string} id | 
				
			||||
     */ | 
				
			||||
    removeUser(id) { | 
				
			||||
        this.users = this.users.filter(u => u.id !== id); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @returns {boolean} | 
				
			||||
     */ | 
				
			||||
    hasLeader() { | 
				
			||||
        return !!this.leaderId; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @param {string} id | 
				
			||||
     * @returns {boolean} | 
				
			||||
     */ | 
				
			||||
    isLeader(id) { | 
				
			||||
        return this.leaderId === id; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @param {string} id | 
				
			||||
     */ | 
				
			||||
    setLeader(id) { | 
				
			||||
        if (!this.getUser(id)) { | 
				
			||||
            throw new Error('user_not_in_lobby'); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        this.leaderId = id; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @returns {User|undefined} | 
				
			||||
     */ | 
				
			||||
    getLeader() { | 
				
			||||
        return this.users.find(u => u.id === this.leaderId) | 
				
			||||
    } | 
				
			||||
}; | 
				
			||||
@ -0,0 +1,5 @@ | 
				
			||||
module.exports = class User { | 
				
			||||
    constructor(id) { | 
				
			||||
        this.id = id; | 
				
			||||
    } | 
				
			||||
}; | 
				
			||||
@ -0,0 +1,44 @@ | 
				
			||||
const express = require("express"); | 
				
			||||
const socketIO = require("socket.io"); | 
				
			||||
 | 
				
			||||
const service = require("./service.js"); | 
				
			||||
const state = require("./state.js"); | 
				
			||||
 | 
				
			||||
const PORT = 3001; | 
				
			||||
 | 
				
			||||
const app = express(); | 
				
			||||
const server = app.listen(PORT, () => console.log(`Example app listening on port ${PORT}!`)); | 
				
			||||
const io = socketIO(server); | 
				
			||||
 | 
				
			||||
app.get('/', (req, res) => res.send('<pre>' + JSON.stringify(state) + '</pre>')); | 
				
			||||
 | 
				
			||||
io.on('connection', socket => { | 
				
			||||
    const socketId = socket.id; | 
				
			||||
 | 
				
			||||
    console.log('a user connected', socketId); | 
				
			||||
 | 
				
			||||
    const lobby = service.joinLobby(socketId); | 
				
			||||
    socket.join(lobby.name); | 
				
			||||
    socket.emit('welcome', {lobby: lobby.name}); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    socket.on('disconnect', (reason) => { | 
				
			||||
        console.log('Disconnected:', socketId); | 
				
			||||
        service.leaveLobby(socketId); | 
				
			||||
    }); | 
				
			||||
 | 
				
			||||
    socket.on('join_lobby', (lobbyId, callback) => { | 
				
			||||
        console.log(`${socketId} wants to join '${lobbyId}'.`); | 
				
			||||
 | 
				
			||||
        // Leave current lobby first
 | 
				
			||||
        service.leaveLobby(socketId); | 
				
			||||
        const lobby = service.joinLobby(socketId, lobbyId); | 
				
			||||
 | 
				
			||||
        socket.join(lobby.name); | 
				
			||||
 | 
				
			||||
        callback(null, { | 
				
			||||
            status: 'ok', | 
				
			||||
            lobby: lobby.name | 
				
			||||
        }); | 
				
			||||
    }); | 
				
			||||
}); | 
				
			||||
@ -0,0 +1,43 @@ | 
				
			||||
const User = require("./User.js"); | 
				
			||||
const state = require("./state.js"); | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * | 
				
			||||
 * @param {string} socketId | 
				
			||||
 * @param {number|undefined} lobbyId | 
				
			||||
 * @returns {Lobby} | 
				
			||||
 */ | 
				
			||||
function joinLobby(socketId, lobbyId=undefined) { | 
				
			||||
    let lobby = state.getLobby(lobbyId); | 
				
			||||
    if (!lobby) { | 
				
			||||
        lobby = state.createRandomLobby(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    lobby.addUser(new User(socketId)); | 
				
			||||
 | 
				
			||||
    if (!lobby.hasLeader()) { | 
				
			||||
        lobby.setLeader(socketId); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    state.lobbies[lobby.name] = lobby; | 
				
			||||
    return lobby; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
function leaveLobby(socketId) { | 
				
			||||
    Object.keys(state.lobbies).forEach(lobbyId => { | 
				
			||||
        const lobby = state.getLobby(lobbyId); | 
				
			||||
 | 
				
			||||
        lobby.removeUser(socketId); | 
				
			||||
 | 
				
			||||
        if (!lobby.hasUsers()) { | 
				
			||||
            state.removeLobby(lobbyId); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (lobby.getLeader() === socketId) { | 
				
			||||
            lobby.setRandomLeader(); | 
				
			||||
        } | 
				
			||||
    }); | 
				
			||||
} | 
				
			||||
 | 
				
			||||
module.exports = {joinLobby, leaveLobby}; | 
				
			||||
@ -0,0 +1,62 @@ | 
				
			||||
const Lobby = require("./Lobby.js"); | 
				
			||||
const User = require("./User.js"); | 
				
			||||
const {getRandomInt} = require("./util.js"); | 
				
			||||
 | 
				
			||||
class State { | 
				
			||||
    /** | 
				
			||||
     * @type {Object.<string, Lobby>} | 
				
			||||
     */ | 
				
			||||
    lobbies = {}; | 
				
			||||
    lobbyCount = 0; | 
				
			||||
 | 
				
			||||
    constructor() { | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * @returns {Lobby} | 
				
			||||
     */ | 
				
			||||
    createRandomLobby() { | 
				
			||||
        let lobby = undefined; | 
				
			||||
 | 
				
			||||
        while (!lobby) { | 
				
			||||
            const id = getRandomInt(100, Math.max(1000, this.lobbyCount * 2)); | 
				
			||||
            lobby = this.createLobby(id); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return lobby; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * | 
				
			||||
     * @param lobbyId | 
				
			||||
     * @returns {Lobby|undefined} | 
				
			||||
     */ | 
				
			||||
    getLobby(lobbyId) { | 
				
			||||
        if (!lobbyId || !this.lobbies.hasOwnProperty(lobbyId)) { | 
				
			||||
            return undefined; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return this.lobbies[lobbyId]; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns undefined when the lobby already exists. | 
				
			||||
     * @param {number} lobbyId | 
				
			||||
     * @returns {Lobby|undefined} | 
				
			||||
     */ | 
				
			||||
    createLobby(lobbyId) { | 
				
			||||
        if (this.lobbies.hasOwnProperty(lobbyId)) { | 
				
			||||
            return undefined; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        this.lobbyCount += 1; | 
				
			||||
        return new Lobby(lobbyId); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    removeLobby(lobbyId) { | 
				
			||||
        this.lobbyCount -= 1; | 
				
			||||
        delete this.lobbies[lobbyId]; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
module.exports = new State(); | 
				
			||||
@ -0,0 +1,15 @@ | 
				
			||||
/** | 
				
			||||
 * Generates random int | 
				
			||||
 * @param {number} min, inclusive | 
				
			||||
 * @param {number} max, exclusive | 
				
			||||
 * @returns {number} | 
				
			||||
 */ | 
				
			||||
function getRandomInt(min, max) { | 
				
			||||
    min = Math.ceil(min); | 
				
			||||
    max = Math.floor(max); | 
				
			||||
    return Math.floor(Math.random() * (max - min)) + min; | 
				
			||||
} | 
				
			||||
 | 
				
			||||
module.exports = { | 
				
			||||
    getRandomInt | 
				
			||||
}; | 
				
			||||
@ -0,0 +1,15 @@ | 
				
			||||
const express = require('express'); | 
				
			||||
const state = require('./state.js'); | 
				
			||||
const b = require('./b.js'); | 
				
			||||
 | 
				
			||||
const PORT = 3002; | 
				
			||||
 | 
				
			||||
const app = express(); | 
				
			||||
const server = app.listen(PORT, () => console.log(`Example app listening on port ${PORT}!`)); | 
				
			||||
 | 
				
			||||
app.get('/', (req, res) => { | 
				
			||||
    let i = state.a; | 
				
			||||
    b.test(i += 1); | 
				
			||||
 | 
				
			||||
    return res.send('<pre>' + JSON.stringify(state) + '</pre>') | 
				
			||||
}); | 
				
			||||
@ -0,0 +1,7 @@ | 
				
			||||
const state = require('./state.js'); | 
				
			||||
 | 
				
			||||
module.exports = { | 
				
			||||
    test: (i) => { | 
				
			||||
        state.setA(i); | 
				
			||||
    } | 
				
			||||
}; | 
				
			||||
@ -0,0 +1,12 @@ | 
				
			||||
class State { | 
				
			||||
    a = 3; | 
				
			||||
    constructor() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    setA(i) { | 
				
			||||
        this.a = i; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
module.exports = new State(); | 
				
			||||
@ -0,0 +1,25 @@ | 
				
			||||
import React, {useEffect} from 'react'; | 
				
			||||
import {Col, Progress} from "antd" | 
				
			||||
import socket from "../util/socket"; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
const Lobby = () => { | 
				
			||||
    useEffect(() => { | 
				
			||||
        socket.on("SENDING_NEW_TIME", (data: string) => { | 
				
			||||
 | 
				
			||||
        }); | 
				
			||||
 | 
				
			||||
        return () => { | 
				
			||||
            socket.off("SENDING_NEW_TIME"); | 
				
			||||
        } | 
				
			||||
    }); | 
				
			||||
 | 
				
			||||
    return ( | 
				
			||||
        <Col className="sider" span={4} offset={10}> | 
				
			||||
            <h1>Centurion!</h1> | 
				
			||||
        </Col> | 
				
			||||
 | 
				
			||||
    ); | 
				
			||||
}; | 
				
			||||
 | 
				
			||||
export default Lobby; | 
				
			||||
@ -1,3 +1,23 @@ | 
				
			||||
import io from "socket.io-client"; | 
				
			||||
 | 
				
			||||
export default io("http://localhost:3001"); | 
				
			||||
 | 
				
			||||
const socket = io("http://localhost:3001"); | 
				
			||||
export default socket; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Promisify emit. | 
				
			||||
 * @param event | 
				
			||||
 * @param arg | 
				
			||||
 * @param callback | 
				
			||||
 */ | 
				
			||||
export function emit(event: string, arg: any) { | 
				
			||||
    return new Promise((resolve, reject) => { | 
				
			||||
        socket.emit(event, arg, (err: any, res: any) => { | 
				
			||||
            if (err) { | 
				
			||||
                return reject(err); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            resolve(res); | 
				
			||||
        }) | 
				
			||||
    }) | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue