checkpoint
This commit is contained in:
parent
b7db38b349
commit
2d185b9410
@ -1,3 +1,3 @@
|
||||
# chat-app
|
||||
|
||||
I have no idea what this will be, but it's my chunkiest setup-looking repo thingy yet.
|
||||
I have no idea what this will be.
|
||||
|
14
build/Channel.js
Normal file
14
build/Channel.js
Normal file
@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Channel = void 0;
|
||||
function isLobby(_id) {
|
||||
return _id !== undefined;
|
||||
}
|
||||
var Channel = /** @class */ (function () {
|
||||
function Channel(_id) {
|
||||
this._id = _id;
|
||||
this.isLobby = isLobby(this._id);
|
||||
}
|
||||
return Channel;
|
||||
}());
|
||||
exports.Channel = Channel;
|
@ -19,8 +19,9 @@ exports.Client = void 0;
|
||||
var events_1 = require("events");
|
||||
var Client = /** @class */ (function (_super) {
|
||||
__extends(Client, _super);
|
||||
function Client(ws) {
|
||||
function Client(ws, server) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.server = server;
|
||||
_this.ws = ws;
|
||||
_this.bindEventListeners();
|
||||
return _this;
|
||||
@ -40,13 +41,26 @@ var Client = /** @class */ (function (_super) {
|
||||
}
|
||||
});
|
||||
this.on('hi', function (msg) {
|
||||
console.log(msg);
|
||||
_this.sendArray([{
|
||||
m: 'hi'
|
||||
}]);
|
||||
});
|
||||
this.on('a', function (msg) {
|
||||
if (!msg.message)
|
||||
return;
|
||||
_this.sendChatMessage(msg);
|
||||
});
|
||||
};
|
||||
Client.prototype.sendArray = function (arr) {
|
||||
var jmsgs = JSON.stringify(arr);
|
||||
this.ws.send(jmsgs);
|
||||
};
|
||||
Client.prototype.sendChatMessage = function (msg) {
|
||||
console.log("Received chat message: " + msg.message);
|
||||
this.server.wsh.clients.forEach(function (cl, id) {
|
||||
cl.sendArray([{ m: 'a', a: msg.message }]);
|
||||
});
|
||||
};
|
||||
return Client;
|
||||
}(events_1.EventEmitter));
|
||||
exports.Client = Client;
|
||||
|
@ -29,7 +29,7 @@ var Server = /** @class */ (function (_super) {
|
||||
_this.bindEventListeners();
|
||||
_this.logger = new Logger_1.Logger('server', chalk.green);
|
||||
_this.logger.debug("port: " + PORT);
|
||||
_this.wsh = new WebSocketHandler_1.WebSocketHandler();
|
||||
_this.wsh = new WebSocketHandler_1.WebSocketHandler(_this);
|
||||
_this.ws = new WebServer_1.WebServer(parseInt(PORT));
|
||||
_this.ws.linkWebSocketServer(_this.wsh.wss);
|
||||
_this.emit('start');
|
||||
|
@ -14,33 +14,6 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
exports.WebSocketHandler = void 0;
|
||||
var WebSocket = require("ws");
|
||||
@ -50,8 +23,9 @@ var chalk = require("chalk");
|
||||
var Client_1 = require("./Client");
|
||||
var WebSocketHandler = /** @class */ (function (_super) {
|
||||
__extends(WebSocketHandler, _super);
|
||||
function WebSocketHandler() {
|
||||
function WebSocketHandler(server) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.server = server;
|
||||
_this.bindEventListeners();
|
||||
_this.logger = new Logger_1.Logger('WebSocketHandler', chalk.yellow);
|
||||
_this.clients = new Map();
|
||||
@ -66,40 +40,18 @@ var WebSocketHandler = /** @class */ (function (_super) {
|
||||
});
|
||||
this.on('startwss', function () {
|
||||
_this.logger.log('Starting WebSocket server...');
|
||||
var clientIDGetter = _this.generateClientMapID();
|
||||
var nextClientID = 0;
|
||||
_this.wss = new WebSocket.Server({
|
||||
noServer: true
|
||||
});
|
||||
_this.wss.on('connection', function (ws, req) {
|
||||
_this.clients.set(clientIDGetter.next().value, new Client_1.Client(ws));
|
||||
_this.clients.set(nextClientID++, new Client_1.Client(ws, _this.server));
|
||||
});
|
||||
_this.wss.on('close', function () {
|
||||
_this.logger.warn('WebSocket server closed.');
|
||||
});
|
||||
});
|
||||
};
|
||||
WebSocketHandler.prototype.generateClientMapID = function () {
|
||||
var i;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, 0];
|
||||
case 1:
|
||||
_a.sent();
|
||||
i = 0;
|
||||
_a.label = 2;
|
||||
case 2:
|
||||
if (!i) return [3 /*break*/, 5];
|
||||
return [4 /*yield*/, i];
|
||||
case 3:
|
||||
_a.sent();
|
||||
_a.label = 4;
|
||||
case 4:
|
||||
i++;
|
||||
return [3 /*break*/, 2];
|
||||
case 5: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
};
|
||||
return WebSocketHandler;
|
||||
}(events_1.EventEmitter));
|
||||
exports.WebSocketHandler = WebSocketHandler;
|
||||
|
1
dist/index.html
vendored
1
dist/index.html
vendored
@ -7,6 +7,7 @@
|
||||
<title>Document</title>
|
||||
<script defer src="index.js"></script></head>
|
||||
<body>
|
||||
<div id="motd"></div>
|
||||
<div id="chat">
|
||||
<div id="chat-messages"></div>
|
||||
<input type="text" name="chat-input" id="chat-input" class="chat-input" placeholder="You can type here to chat.">
|
||||
|
33
dist/index.js
vendored
33
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -8,7 +8,8 @@
|
||||
"start": "node .",
|
||||
"build": "yarn build-webpack && yarn build-ts",
|
||||
"build-webpack": "npx webpack",
|
||||
"build-ts": "npx tsc"
|
||||
"build-ts": "npx tsc",
|
||||
"test": "yarn build && yarn start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/jquery": "^3.5.6",
|
||||
|
24
src/Channel.ts
Normal file
24
src/Channel.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Client } from "./Client";
|
||||
|
||||
type ChannelID = `${string}`;
|
||||
|
||||
type LobbyID = `lobby${string}` | `test/${string}`;
|
||||
|
||||
function isLobby(_id: ChannelID | LobbyID): _id is LobbyID {
|
||||
return _id !== undefined;
|
||||
}
|
||||
|
||||
class Channel {
|
||||
_id: ChannelID | LobbyID;
|
||||
connectedClients: Client[];
|
||||
isLobby: boolean;
|
||||
|
||||
constructor (_id: string) {
|
||||
this._id = _id;
|
||||
this.isLobby = isLobby(this._id);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
Channel
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import WebSocket = require('ws');
|
||||
import { Server } from './Server';
|
||||
|
||||
class Client extends EventEmitter {
|
||||
ws: WebSocket;
|
||||
server: Server;
|
||||
|
||||
constructor (ws: WebSocket) {
|
||||
constructor (ws: WebSocket, server: Server) {
|
||||
super();
|
||||
|
||||
this.server = server;
|
||||
this.ws = ws;
|
||||
|
||||
this.bindEventListeners();
|
||||
@ -25,14 +28,32 @@ class Client extends EventEmitter {
|
||||
});
|
||||
|
||||
this.on('hi', msg => {
|
||||
this.emit('hi');
|
||||
this.sendArray([{
|
||||
m: 'hi'
|
||||
}]);
|
||||
});
|
||||
|
||||
this.on('a', msg => {
|
||||
if (!msg.message) return;
|
||||
|
||||
this.sendChatMessage(msg);
|
||||
});
|
||||
|
||||
// TODO user data, other messages, maybe cursors
|
||||
}
|
||||
|
||||
sendArray(arr) {
|
||||
let jmsgs = JSON.stringify(arr);
|
||||
this.ws.send(jmsgs);
|
||||
}
|
||||
|
||||
sendChatMessage(msg) { // TODO move this to Channel
|
||||
console.log(`Received chat message: ${msg.message}`);
|
||||
|
||||
this.server.wsh.clients.forEach((cl, id) => {
|
||||
cl.sendArray([{m:'a', a: msg.message}])
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
|
@ -20,7 +20,7 @@ class Server extends EventEmitter {
|
||||
|
||||
this.logger = new Logger('server', chalk.green);
|
||||
this.logger.debug(`port: ${PORT}`);
|
||||
this.wsh = new WebSocketHandler();
|
||||
this.wsh = new WebSocketHandler(this);
|
||||
this.ws = new WebServer(parseInt(PORT));
|
||||
|
||||
this.ws.linkWebSocketServer(this.wsh.wss);
|
||||
|
@ -3,15 +3,18 @@ import { EventEmitter } from 'events';
|
||||
import { Logger } from './Logger';
|
||||
import chalk = require('chalk');
|
||||
import { Client } from './Client';
|
||||
import { Server } from './Server';
|
||||
|
||||
class WebSocketHandler extends EventEmitter {
|
||||
wss: WebSocket.Server;
|
||||
logger: Logger;
|
||||
clients: Map<number, Client>;
|
||||
server: Server;
|
||||
|
||||
constructor () {
|
||||
constructor (server: Server) {
|
||||
super();
|
||||
|
||||
this.server = server;
|
||||
this.bindEventListeners();
|
||||
|
||||
this.logger = new Logger('WebSocketHandler', chalk.yellow);
|
||||
@ -28,14 +31,14 @@ class WebSocketHandler extends EventEmitter {
|
||||
|
||||
this.on('startwss', () => {
|
||||
this.logger.log('Starting WebSocket server...');
|
||||
let clientIDGetter = this.generateClientMapID();
|
||||
let nextClientID = 0
|
||||
|
||||
this.wss = new WebSocket.Server({
|
||||
noServer: true
|
||||
});
|
||||
|
||||
this.wss.on('connection', (ws, req) => {
|
||||
this.clients.set((clientIDGetter.next().value as any), new Client(ws));
|
||||
this.clients.set(nextClientID++, new Client(ws, this.server));
|
||||
});
|
||||
|
||||
this.wss.on('close', () => {
|
||||
@ -43,13 +46,6 @@ class WebSocketHandler extends EventEmitter {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
* generateClientMapID() {
|
||||
yield 0;
|
||||
for (let i = 0; i; i++) {
|
||||
yield i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
|
@ -30,6 +30,20 @@ class Client extends EventEmitter {
|
||||
m: 'hi'
|
||||
}]);
|
||||
});
|
||||
|
||||
this.ws.addEventListener('close', evt => {
|
||||
console.log('WebSocket disconnected');
|
||||
if (this.started) {
|
||||
setTimeout(() => {
|
||||
this.emit('motd', 'Connecting...');
|
||||
this.connect();
|
||||
}, 1000);
|
||||
} else {
|
||||
this.ws = undefined;
|
||||
this.emit('motd', 'Offline');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
@ -45,7 +59,7 @@ class Client extends EventEmitter {
|
||||
|
||||
bindEventListeners() {
|
||||
this.on('hi', msg => {
|
||||
console.log(msg);
|
||||
'motd' in msg ? this.emit('motd', msg.motd) : this.emit('motd', 'Connected');
|
||||
});
|
||||
|
||||
this.ws.addEventListener('message', evt => {
|
||||
|
@ -7,6 +7,7 @@
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="motd"></div>
|
||||
<div id="chat">
|
||||
<div id="chat-messages"></div>
|
||||
<input type="text" name="chat-input" id="chat-input" class="chat-input" placeholder="You can type here to chat.">
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { Client } from "./Client";
|
||||
import "./style.scss";
|
||||
import * as $ from "jquery";
|
||||
|
||||
(globalThis as any)['$'] = $;
|
||||
|
||||
(() => {
|
||||
let secure = globalThis.location.protocol == "https";
|
||||
@ -12,6 +15,65 @@ import "./style.scss";
|
||||
|
||||
gClient.start();
|
||||
|
||||
gClient.on('motd', async message => {
|
||||
let motd = $("#motd");
|
||||
|
||||
motd.fadeOut(() => {
|
||||
motd.html(message).fadeIn();
|
||||
});
|
||||
});
|
||||
|
||||
let chat = {
|
||||
send: (txt: string | number | string[]) => {
|
||||
console.log(`Sending chat message: ${txt}`);
|
||||
gClient.sendArray([{
|
||||
m: 'a',
|
||||
message: txt
|
||||
}]);
|
||||
},
|
||||
receive: (msg: any) => {
|
||||
// TODO write chat receive
|
||||
if (!msg.a) return;
|
||||
|
||||
let nameDiv = `<div class="chat-name"></div>`
|
||||
let messageDiv = `<div class="chat-message"></div>`
|
||||
|
||||
let li = `<li>Anonymous: ${msg.a}</li>`;
|
||||
|
||||
$('#chat-messages').append(li);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', evt => {
|
||||
if (evt.code == 'Enter' || evt.code == 'Escape') {
|
||||
let chatInput = $("#chat-input");
|
||||
let chatFocused = chatInput.is(':focus');
|
||||
|
||||
if (chatFocused == true) {
|
||||
if (evt.code == 'Enter') {
|
||||
let text = chatInput.val();
|
||||
|
||||
if (text !== '') {
|
||||
chat.send(text);
|
||||
chatInput.val('');
|
||||
}
|
||||
}
|
||||
|
||||
chatInput.trigger('blur');
|
||||
} else {
|
||||
chatInput.trigger('focus');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
gClient.on('a', msg => {
|
||||
if (!msg.a) return;
|
||||
|
||||
console.log(`Received chat message: ${msg.a}`);
|
||||
|
||||
chat.receive(msg);
|
||||
});
|
||||
|
||||
(globalThis as any).app = {
|
||||
client: gClient
|
||||
}
|
||||
|
@ -19,7 +19,10 @@ body {
|
||||
margin-left: 1.5%;
|
||||
|
||||
#chat-messages {
|
||||
|
||||
.chat-message {
|
||||
display: inline;
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
|
||||
#chat-input {
|
||||
@ -28,3 +31,21 @@ body {
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.spin {
|
||||
animation: spin 1s linear infinite;
|
||||
-webkit-animation: spin 1s linear infinite;
|
||||
-moz-animation: spin 1s linear infinite;
|
||||
-o-animation: spin 1s linear infinite;
|
||||
-ms-animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user