initial commit
This commit is contained in:
5
src/server/controllers/ControllerBase.ts
Normal file
5
src/server/controllers/ControllerBase.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { LoggingService } from "../../common/LoggingService";
|
||||
|
||||
export class ControllerBase {
|
||||
protected logger = new LoggingService();
|
||||
}
|
77
src/server/controllers/SessionController.ts
Normal file
77
src/server/controllers/SessionController.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import { LoggingService } from "../../common/LoggingService";
|
||||
import { GameSession } from "../../game/GameSession";
|
||||
import { NetworkPlayer } from "../../game/entities/player/NetworkPlayer";
|
||||
|
||||
import { ControllerBase } from "./ControllerBase";
|
||||
|
||||
export class SessionController extends ControllerBase{
|
||||
private static sessions: any = {};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.logger.info('SessionController created');
|
||||
}
|
||||
|
||||
createSession(data: any, socketId: string): any {
|
||||
const { user, sessionName } = data;
|
||||
const player = new NetworkPlayer(user, socketId);
|
||||
const session = new GameSession(player, sessionName);
|
||||
SessionController.sessions[session.id] = session;
|
||||
|
||||
return {
|
||||
status: 'ok',
|
||||
sessionId: session.id,
|
||||
playerId: player.id
|
||||
};
|
||||
}
|
||||
|
||||
joinSession(data: any, socketId: string): any {
|
||||
this.logger.debug('joinSession data :>> ')
|
||||
this.logger.object(data);
|
||||
const { user, sessionId } = data;
|
||||
const session = SessionController.sessions[sessionId];
|
||||
const player = new NetworkPlayer(user, socketId);
|
||||
session.addPlayer(player);
|
||||
return {
|
||||
status: 'ok',
|
||||
sessionId: session.id,
|
||||
playerId: player.id
|
||||
};
|
||||
}
|
||||
|
||||
startSession(data: any): any {
|
||||
const sessionId: string = data.sessionId;
|
||||
const seed: string | undefined = data.seed;
|
||||
const session = SessionController.sessions[sessionId];
|
||||
|
||||
if (!session) {
|
||||
return ({
|
||||
status: 'error',
|
||||
message: 'Session not found'
|
||||
});
|
||||
} else if (session.gameInProgress) {
|
||||
return {
|
||||
status: 'error',
|
||||
message: 'Game already in progress'
|
||||
};
|
||||
} else {
|
||||
const missingHumans = session.maxPlayers - session.numPlayers;
|
||||
for (let i = 0; i < missingHumans; i++) {
|
||||
session.addPlayer(session.createPlayerAI(i));
|
||||
}
|
||||
session.start(seed);
|
||||
return {
|
||||
status: 'ok'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getSession(id: string) {
|
||||
return SessionController.sessions[id];
|
||||
}
|
||||
|
||||
deleteSession(id: string) {
|
||||
delete SessionController.sessions[id];
|
||||
}
|
||||
}
|
89
src/server/index.html
Normal file
89
src/server/index.html
Normal file
@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<title>Socket.IO chat</title>
|
||||
<style>
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
resize: none;
|
||||
}
|
||||
#response {
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ul id="messages"></ul>
|
||||
<form id="form" action="">
|
||||
<p>
|
||||
<select id="event" autocomplete="off">
|
||||
<option value="">Select event</option>
|
||||
</select>
|
||||
</p>
|
||||
<!-- <p><input id="room" autocomplete="off" /></p> -->
|
||||
<p><textarea id="message" autocomplete="off" placeholder="Data"></textarea></p>
|
||||
<p><button>Send</button></p>
|
||||
<p><textarea id="response" autocomplete="off" placeholder="Response"></textarea></p>
|
||||
</form>
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
const socket = io();
|
||||
|
||||
const form = document.getElementById("form");
|
||||
const event = document.getElementById("event");
|
||||
// const room = document.getElementById("room");
|
||||
const message = document.getElementById("message");
|
||||
const responseEl = document.getElementById("response");
|
||||
const messages = document.getElementById("messages");
|
||||
|
||||
const options = [
|
||||
{ value: "createSession", default: '{"user": "arhuako"}' },
|
||||
{ value: "startSession", default: '{"sessionId": "arhuako"}' },
|
||||
{ value: "joinSession", default: '{"user": "pepe", "sessionId": "arhuako"}' },
|
||||
{ value: "leaveSession", default: '{"user": "pepe", "sessionId": "arhuako"}' },
|
||||
{ value: "chat message", default: "chat message" }
|
||||
];
|
||||
|
||||
|
||||
//`<option value="${option.value}">${option.value}</option>`
|
||||
options.forEach((option) => {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = option.value;
|
||||
opt.textContent = option.value;
|
||||
event.appendChild(opt);
|
||||
});
|
||||
|
||||
event.addEventListener("change", (e) => {
|
||||
const option = options.find((option) => option.value === e.target.value);
|
||||
message.value = option.default;
|
||||
});
|
||||
|
||||
const getMessage = (msg) => {
|
||||
if (msg.startsWith("{") && msg.endsWith("}")) return JSON.parse(msg);
|
||||
return msg;
|
||||
};
|
||||
|
||||
form.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
if (event.value.trim() && message.value.trim()) {
|
||||
const response = await socket.emitWithAck(event.value.trim(), getMessage(message.value.trim()));
|
||||
console.log('response :>> ', response);
|
||||
message.value = "";
|
||||
const responseStr = JSON.stringify(response, null, 2);
|
||||
responseEl.value = !responseEl.value ? responseStr : responseEl.value + '\n---\n ' + responseStr;
|
||||
event.selectedIndex = 0;
|
||||
}
|
||||
});
|
||||
|
||||
socket.onAny((eventName, msg) => {
|
||||
const item = document.createElement("li");
|
||||
item.textContent = `${eventName}: ${msg}`;
|
||||
messages.appendChild(item);
|
||||
window.scrollTo(0, document.body.scrollHeight);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
25
src/server/index.ts
Normal file
25
src/server/index.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import express from 'express';
|
||||
import http from 'http';
|
||||
import cors from 'cors';
|
||||
import { join } from 'path';
|
||||
|
||||
import { NetworkClientNotifier } from '../game/NetworkClientNotifier';
|
||||
import { SocketIoService } from './services/SocketIoService';
|
||||
|
||||
const clientNotifier = new NetworkClientNotifier();
|
||||
const app = express();
|
||||
const httpServer = http.createServer(app);
|
||||
const socketIoService = new SocketIoService(httpServer);
|
||||
clientNotifier.setSocket(socketIoService.getServer());
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
console.log('__dirname :>> ', __dirname);
|
||||
|
||||
app.use(cors());
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(join(__dirname, 'index.html'));
|
||||
});
|
||||
|
||||
httpServer.listen(PORT, () => {
|
||||
console.log(`listening on *:${PORT}`);
|
||||
});
|
5
src/server/services/ServiceBase.ts
Normal file
5
src/server/services/ServiceBase.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { LoggingService } from "../../common/LoggingService";
|
||||
|
||||
export class ServiceBase {
|
||||
protected logger = new LoggingService();
|
||||
}
|
75
src/server/services/SocketIoService.ts
Normal file
75
src/server/services/SocketIoService.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import { Server as HttpServer } from "http";
|
||||
import { ServiceBase } from "./ServiceBase";
|
||||
import { Server } from "socket.io";
|
||||
import { SessionController } from "../controllers/SessionController";
|
||||
|
||||
export class SocketIoService extends ServiceBase{
|
||||
io: Server
|
||||
constructor(private httpServer: HttpServer) {
|
||||
super()
|
||||
this.io = this.socketIo(httpServer);
|
||||
this.initListeners();
|
||||
}
|
||||
|
||||
public getServer(): Server {
|
||||
return this.io;
|
||||
}
|
||||
|
||||
private initListeners() {
|
||||
const sessionController = new SessionController();
|
||||
this.io.on('connection', (socket) => {
|
||||
console.log(`connect ${socket.id}`);
|
||||
if (socket.recovered) {
|
||||
// recovery was successful: socket.id, socket.rooms and socket.data were restored
|
||||
console.log("recovered!");
|
||||
console.log("socket.rooms:", socket.rooms);
|
||||
console.log("socket.data:", socket.data);
|
||||
} else {
|
||||
console.log("new connection");
|
||||
socket.join('room-general')
|
||||
socket.data.foo = "bar";
|
||||
}
|
||||
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
console.log('user disconnected');
|
||||
});
|
||||
|
||||
socket.on('createSession', (data, callback) => {
|
||||
const response = sessionController.createSession(data, socket.id);
|
||||
callback(response);
|
||||
});
|
||||
|
||||
socket.on('startSession', (data, callback) => {
|
||||
const response = sessionController.startSession(data);
|
||||
callback(response);
|
||||
});
|
||||
|
||||
socket.on('joinSession', (data, callback) => {
|
||||
const response = sessionController.joinSession(data, socket.id);
|
||||
callback(response);
|
||||
});
|
||||
|
||||
// socket.on('chat message', (msg, callback) => {
|
||||
// io.emit('chat message', msg);
|
||||
// callback({
|
||||
// status: 'ok',
|
||||
// message: 'Message received',
|
||||
// })
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
private socketIo(httpServer: HttpServer): Server {
|
||||
return new Server(httpServer, {
|
||||
cors: {
|
||||
origin: '*',
|
||||
},
|
||||
connectionStateRecovery: {
|
||||
maxDisconnectionDuration: 15 * 60 * 1000,
|
||||
skipMiddlewares: true,
|
||||
},
|
||||
connectTimeout: 15 * 60 * 1000,
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user