basic Websocket client-server
This commit is contained in:
75
package-lock.json
generated
75
package-lock.json
generated
@@ -4,8 +4,14 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": "^9.0.0",
|
||||||
|
"ws": "^8.10.0"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.11.5",
|
"@types/node": "^18.11.5",
|
||||||
|
"@types/uuid": "^8.3.4",
|
||||||
|
"@types/ws": "^8.5.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -15,6 +21,21 @@
|
|||||||
"integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==",
|
"integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/uuid": {
|
||||||
|
"version": "8.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
|
||||||
|
"integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/ws": {
|
||||||
|
"version": "8.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
|
||||||
|
"integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.8.4",
|
"version": "4.8.4",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
|
||||||
@@ -27,6 +48,34 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.2.0"
|
"node": ">=4.2.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz",
|
||||||
|
"integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": "^5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -36,11 +85,37 @@
|
|||||||
"integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==",
|
"integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/uuid": {
|
||||||
|
"version": "8.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
|
||||||
|
"integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/ws": {
|
||||||
|
"version": "8.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
|
||||||
|
"integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.8.4",
|
"version": "4.8.4",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
|
||||||
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
|
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "8.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz",
|
||||||
|
"integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==",
|
||||||
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.11.5",
|
"@types/node": "^18.11.5",
|
||||||
|
"@types/uuid": "^8.3.4",
|
||||||
|
"@types/ws": "^8.5.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": "^9.0.0",
|
||||||
|
"ws": "^8.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ class GameArea {
|
|||||||
deleteKey(key: string) {
|
deleteKey(key: string) {
|
||||||
key = key.toLowerCase();
|
key = key.toLowerCase();
|
||||||
var i = this.keys.indexOf(key);
|
var i = this.keys.indexOf(key);
|
||||||
if (i != -1)
|
if (i != -1) {
|
||||||
this.keys.splice(i, 1);
|
this.keys.splice(i, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
clear() {
|
clear() {
|
||||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class MovingRectangle extends Rectangle implements Moving {
|
|||||||
this.speed = baseSpeed;
|
this.speed = baseSpeed;
|
||||||
}
|
}
|
||||||
move(delta: number) { // Math.floor WIP until VectorInteger debug
|
move(delta: number) { // Math.floor WIP until VectorInteger debug
|
||||||
console.log("delta: "+ delta);
|
// console.log("delta: "+ delta);
|
||||||
// console.log("speed: "+ this.speed);
|
// console.log("speed: "+ this.speed);
|
||||||
// console.log("speed*delta: "+ this.speed * delta);
|
// console.log("speed*delta: "+ this.speed * delta);
|
||||||
this.pos.x += Math.floor(this.dir.x * this.speed * delta);
|
this.pos.x += Math.floor(this.dir.x * this.speed * delta);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
}
|
}
|
||||||
#canvas-container {
|
#canvas-container {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* border: dashed red 5px; */
|
border: dashed red 5px;
|
||||||
/* max-height: 80vh; */
|
/* max-height: 80vh; */
|
||||||
/* overflow: hidden; */
|
/* overflow: hidden; */
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
background-color: #333333;
|
background-color: #333333;
|
||||||
max-width: 75vw;
|
max-width: 75vw;
|
||||||
/* max-height: 100vh; */
|
/* max-height: 100vh; */
|
||||||
/* width: 80%; */
|
width: 80%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import {TextElem, TextNumericValue} from "./class/Text.js";
|
|||||||
import * as d from "./draw.js";
|
import * as d from "./draw.js";
|
||||||
import {gameLoop, newRound} from "./gameLoop.js"
|
import {gameLoop, newRound} from "./gameLoop.js"
|
||||||
import {random} from "./utils.js";
|
import {random} from "./utils.js";
|
||||||
|
import {socket} from "./ws.js";
|
||||||
|
|
||||||
|
|
||||||
/* Keys
|
/* Keys
|
||||||
Player 1: W/S
|
Player 1: W/S
|
||||||
@@ -31,10 +33,56 @@ export let h_grid_mid: Rectangle;
|
|||||||
export let h_grid_u1: Rectangle;
|
export let h_grid_u1: Rectangle;
|
||||||
export let h_grid_d1: Rectangle;
|
export let h_grid_d1: Rectangle;
|
||||||
|
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
initGame();
|
||||||
|
initGameClientOnly();
|
||||||
|
console.log("socket state %i", socket.readyState);
|
||||||
|
}
|
||||||
|
|
||||||
function startGame()
|
function startGame()
|
||||||
{
|
{
|
||||||
pong = new GameArea();
|
// Start
|
||||||
|
d.drawInit();
|
||||||
|
window.addEventListener('keydown', function (e) {
|
||||||
|
pong.addKey(e.key);
|
||||||
|
});
|
||||||
|
window.addEventListener('keyup', function (e) {
|
||||||
|
pong.deleteKey(e.key);
|
||||||
|
});
|
||||||
|
pong.interval = window.setInterval(gameLoop, 15); // min interval on Firefox seems to be 15. Chrome can go lower.
|
||||||
|
setTimeout(newRound, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initGameClientOnly()
|
||||||
|
{
|
||||||
|
let pos = new VectorInteger;
|
||||||
|
|
||||||
|
// Const
|
||||||
|
const w = pong.canvas.width;
|
||||||
|
const h = pong.canvas.height;
|
||||||
|
const w_mid = Math.floor(w/2);
|
||||||
|
const h_mid = Math.floor(h/2);
|
||||||
|
const gridSize = Math.floor(w/500);
|
||||||
|
|
||||||
|
// Grid
|
||||||
|
pos.assign(0, h_mid);
|
||||||
|
w_grid_mid = new Rectangle(pong.ctx, pos, "darkgreen", w, gridSize);
|
||||||
|
pos.assign(0, h/4);
|
||||||
|
w_grid_u1 = new Rectangle(pong.ctx, pos, "darkgreen", w, gridSize);
|
||||||
|
pos.assign(0, h-h/4);
|
||||||
|
w_grid_d1 = new Rectangle(pong.ctx, pos, "darkgreen", w, gridSize);
|
||||||
|
pos.assign(w_mid, 0);
|
||||||
|
h_grid_mid = new Rectangle(pong.ctx, pos, "darkgreen", gridSize, h);
|
||||||
|
pos.assign(w/4, 0);
|
||||||
|
h_grid_u1 = new Rectangle(pong.ctx, pos, "darkgreen", gridSize, h);
|
||||||
|
pos.assign(w-w/4, 0);
|
||||||
|
h_grid_d1 = new Rectangle(pong.ctx, pos, "darkgreen", gridSize, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initGame()
|
||||||
|
{
|
||||||
|
pong = new GameArea();
|
||||||
// Const
|
// Const
|
||||||
const w = pong.canvas.width;
|
const w = pong.canvas.width;
|
||||||
const h = pong.canvas.height;
|
const h = pong.canvas.height;
|
||||||
@@ -46,7 +94,6 @@ function startGame()
|
|||||||
const scoreSize = Math.floor(w/16);
|
const scoreSize = Math.floor(w/16);
|
||||||
const midLineSize = Math.floor(w/150);
|
const midLineSize = Math.floor(w/150);
|
||||||
const wallSize = Math.floor(w/100);
|
const wallSize = Math.floor(w/100);
|
||||||
const gridSize = Math.floor(w/500);
|
|
||||||
const playerSpeed = Math.floor(w/1.5); // pixel per second
|
const playerSpeed = Math.floor(w/1.5); // pixel per second
|
||||||
const ballSpeed = Math.floor(w/1.5); // pixel per second
|
const ballSpeed = Math.floor(w/1.5); // pixel per second
|
||||||
|
|
||||||
@@ -75,34 +122,11 @@ function startGame()
|
|||||||
|
|
||||||
pos.assign(w_mid-midLineSize/2, 0+wallSize);
|
pos.assign(w_mid-midLineSize/2, 0+wallSize);
|
||||||
midLine = new Line(pong.ctx, pos, "white", midLineSize, h-wallSize*2, 15);
|
midLine = new Line(pong.ctx, pos, "white", midLineSize, h-wallSize*2, 15);
|
||||||
|
|
||||||
// Grid
|
|
||||||
pos.assign(0, h_mid);
|
|
||||||
w_grid_mid = new Rectangle(pong.ctx, pos, "darkgreen", w, gridSize);
|
|
||||||
pos.assign(0, h/4);
|
|
||||||
w_grid_u1 = new Rectangle(pong.ctx, pos, "darkgreen", w, gridSize);
|
|
||||||
pos.assign(0, h-h/4);
|
|
||||||
w_grid_d1 = new Rectangle(pong.ctx, pos, "darkgreen", w, gridSize);
|
|
||||||
pos.assign(w_mid, 0);
|
|
||||||
h_grid_mid = new Rectangle(pong.ctx, pos, "darkgreen", gridSize, h);
|
|
||||||
pos.assign(w/4, 0);
|
|
||||||
h_grid_u1 = new Rectangle(pong.ctx, pos, "darkgreen", gridSize, h);
|
|
||||||
pos.assign(w-w/4, 0);
|
|
||||||
h_grid_d1 = new Rectangle(pong.ctx, pos, "darkgreen", gridSize, h);
|
|
||||||
|
|
||||||
// Start
|
|
||||||
d.drawInit();
|
|
||||||
window.addEventListener('keydown', function (e) {
|
|
||||||
pong.addKey(e.key);
|
|
||||||
});
|
|
||||||
window.addEventListener('keyup', function (e) {
|
|
||||||
pong.deleteKey(e.key);
|
|
||||||
});
|
|
||||||
pong.interval = window.setInterval(gameLoop, 15); // min interval on Firefox seems to be 15. Chrome can go lower.
|
|
||||||
setTimeout(newRound, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
startGame();
|
init();
|
||||||
|
|
||||||
|
export {startGame}
|
||||||
|
|||||||
@@ -3,4 +3,8 @@ function random(min: number = 0, max: number = 1) {
|
|||||||
return Math.random() * (max - min) + min;
|
return Math.random() * (max - min) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {random}
|
function sleep (ms: number) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
export {random, sleep}
|
||||||
|
|||||||
81
src/client/ws.ts
Normal file
81
src/client/ws.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
import * as g from "./pong.js"
|
||||||
|
import {startGame} from "./pong.js";
|
||||||
|
|
||||||
|
const wsPort = 8042;
|
||||||
|
const wsUrl = "ws://" + document.location.hostname + ":" + wsPort + "/pong";
|
||||||
|
const socket = new WebSocket(wsUrl, "json");
|
||||||
|
|
||||||
|
enum EventTypes {
|
||||||
|
gameUpdate = 1,
|
||||||
|
start,
|
||||||
|
pause,
|
||||||
|
resume
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EventData {
|
||||||
|
type: EventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventGameUpdate implements EventData {
|
||||||
|
type: EventTypes = EventTypes.gameUpdate;
|
||||||
|
player1 = {y: 0};
|
||||||
|
player2 = {y: 0};
|
||||||
|
ball = {x: 0, y: 0, speed: 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.addEventListener("message", logListener);
|
||||||
|
socket.addEventListener("message", matchmakingListener);
|
||||||
|
|
||||||
|
|
||||||
|
function logListener(event: MessageEvent) {
|
||||||
|
console.log("data: " + event.data + " | [" + Date.now() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchmakingListener(event: MessageEvent)
|
||||||
|
{
|
||||||
|
console.log("matchmakingListener");
|
||||||
|
const data: EventData = JSON.parse(event.data);
|
||||||
|
if (data.type == EventTypes.start)
|
||||||
|
{
|
||||||
|
console.log("Event type = start");
|
||||||
|
socket.removeEventListener("message", matchmakingListener);
|
||||||
|
socket.addEventListener("message", inGameListener);
|
||||||
|
startGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function inGameListener(event: MessageEvent)
|
||||||
|
{
|
||||||
|
console.log("inGameListener");
|
||||||
|
const data: EventData = JSON.parse(event.data);
|
||||||
|
switch (data.type) {
|
||||||
|
case EventTypes.gameUpdate:
|
||||||
|
console.log("Event type = gameUpdate");
|
||||||
|
serverGameUpdate(data as EventGameUpdate);
|
||||||
|
break;
|
||||||
|
case EventTypes.pause:
|
||||||
|
console.log("Event type = pause");
|
||||||
|
break;
|
||||||
|
case EventTypes.resume:
|
||||||
|
console.log("Event type = resume");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function serverGameUpdate(data: EventGameUpdate)
|
||||||
|
{
|
||||||
|
g.player1.clear();
|
||||||
|
g.player1.pos.y = Math.floor(data.player1.y);
|
||||||
|
g.player1.update();
|
||||||
|
|
||||||
|
g.player2.clear();
|
||||||
|
g.player2.pos.y = Math.floor(data.player2.y);
|
||||||
|
g.player2.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// socket.addEventListener("open", (event) => {
|
||||||
|
// console.log("socket state %i", socket.readyState);
|
||||||
|
// });
|
||||||
|
|
||||||
|
export {socket}
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
|
|
||||||
// var http = require("http");
|
|
||||||
// var url = require("url");
|
|
||||||
// var fs = require("fs");
|
|
||||||
// var path = require("path");
|
|
||||||
import http from "http";
|
import http from "http";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import { WebSocketServer, WebSocket } from "ws";
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import { random } from "../client/utils.js";
|
||||||
|
|
||||||
const hostname = "localhost";
|
const hostname = "localhost";
|
||||||
const port = 8080;
|
const port = 8080;
|
||||||
const root = "/mnt/c/Users/Lucky/Desktop/code/ft_transcendence/www/";
|
const wsPort = 8042; // pas indispensable d'avoir un autre port si le WebSocket est limité à certaines routes
|
||||||
|
const root = "../../www/";
|
||||||
|
|
||||||
const server = http.createServer((req, res) => {
|
const server = http.createServer((req, res) => {
|
||||||
// var q = new URL(req.url, `http://${req.getHeaders().host}`)
|
// var q = new URL(req.url, `http://${req.getHeaders().host}`)
|
||||||
@@ -36,4 +35,79 @@ const server = http.createServer((req, res) => {
|
|||||||
|
|
||||||
server.listen(port, hostname, () => {
|
server.listen(port, hostname, () => {
|
||||||
console.log(`Pong running at http://${hostname}:${port}/pong.html`);
|
console.log(`Pong running at http://${hostname}:${port}/pong.html`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const wsServer = new WebSocketServer({port: wsPort, path: "/pong"});
|
||||||
|
|
||||||
|
class Client {
|
||||||
|
socket: WebSocket;
|
||||||
|
id: string;
|
||||||
|
isAlive: boolean = true;
|
||||||
|
constructor(socket: WebSocket, id: string) {
|
||||||
|
this.socket = socket;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const clientsArr: Client[] = [];
|
||||||
|
|
||||||
|
|
||||||
|
wsServer.on("connection", (socket, request) => {
|
||||||
|
|
||||||
|
const id = uuidv4();
|
||||||
|
const client = new Client(socket, id);
|
||||||
|
clientsArr.push(client);
|
||||||
|
socket.on("pong", function heartbeat() {
|
||||||
|
client.isAlive = true;
|
||||||
|
console.log("client %s alive at %i", client.id, Date.now());
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("message", function message(data) {
|
||||||
|
console.log("received: %s", data);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.send(JSON.stringify({type: 2})); // start
|
||||||
|
// socket.send("connection success, bravo client " + id);
|
||||||
|
// socket.send("start");
|
||||||
|
// socket.send("json/20");
|
||||||
|
});
|
||||||
|
|
||||||
|
function deleteClient(client: Client)
|
||||||
|
{
|
||||||
|
var i = clientsArr.indexOf(client);
|
||||||
|
if (i != -1) {
|
||||||
|
clientsArr.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pingInterval = setInterval( () => {
|
||||||
|
clientsArr.forEach( (client) => {
|
||||||
|
if (client.isAlive === false) {
|
||||||
|
client.socket.terminate();
|
||||||
|
console.log("client %s is no more at %i :'(", client.id, Date.now());
|
||||||
|
deleteClient(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client.isAlive = false;
|
||||||
|
client.socket.ping();
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
const gameUpdateInterval = setInterval( () => {
|
||||||
|
clientsArr.forEach( (client) => {
|
||||||
|
const update = {
|
||||||
|
type: 1,
|
||||||
|
player1: {y: random(50, 650)},
|
||||||
|
player2: {y: random(50, 650)},
|
||||||
|
ball: {x: 0, y: 0, speed: 0}
|
||||||
|
};
|
||||||
|
client.socket.send(JSON.stringify(update));
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
|
||||||
|
wsServer.on('close', () => {
|
||||||
|
clearInterval(pingInterval);
|
||||||
|
clearInterval(gameUpdateInterval);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user