Finish code
This commit is contained in:
parent
03b7c5b515
commit
d73fbaec86
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"trailingComma": "none",
|
||||||
|
"tabWidth": 4
|
||||||
|
}
|
30
package.json
30
package.json
|
@ -1,17 +1,17 @@
|
||||||
{
|
{
|
||||||
"name": "sync",
|
"name": "sync",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"ws": "^8.14.2"
|
"ws": "^8.14.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
139
src/client.js
139
src/client.js
|
@ -2,79 +2,90 @@ const WebSocket = require("ws");
|
||||||
const { EventEmitter } = require("events");
|
const { EventEmitter } = require("events");
|
||||||
|
|
||||||
class Client extends EventEmitter {
|
class Client extends EventEmitter {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.bindEventListeners();
|
this.bindEventListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
if (!this.started) return;
|
if (!this.started) return;
|
||||||
this.started = true;
|
this.started = true;
|
||||||
|
|
||||||
this.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
connect() {
|
|
||||||
this.ws = new WebSocket(process.env.SYNC_URI);
|
|
||||||
|
|
||||||
this.ws.on("open", () => {});
|
|
||||||
|
|
||||||
this.ws.addEventListener("close", (evt) => {
|
|
||||||
this.emit("disconnected");
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.connect();
|
this.connect();
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.ws.addEventListener("error", (evt) => {
|
|
||||||
this.emit("wserror", evt);
|
|
||||||
this.ws.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.ws.addEventListener("message", (evt) => {
|
|
||||||
try {
|
|
||||||
const str = evt.data.toString();
|
|
||||||
const msg = JSON.parse(str);
|
|
||||||
this.emit(msg.m, msg);
|
|
||||||
} catch (err) {
|
|
||||||
this.emit("parse_error", err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
this.started = false;
|
|
||||||
|
|
||||||
if (this.ws) {
|
|
||||||
this.ws.close();
|
|
||||||
delete this.ws;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
say(msg) {
|
connect() {
|
||||||
try {
|
this.ws = new WebSocket(process.env.SYNC_URI);
|
||||||
if (this.isConnected()) this.ws.send(JSON.stringify(msg));
|
|
||||||
return true;
|
this.ws.on("open", () => {});
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
this.ws.addEventListener("close", evt => {
|
||||||
return false;
|
this.emit("disconnected");
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.connect();
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.ws.addEventListener("error", evt => {
|
||||||
|
this.emit("wserror", evt);
|
||||||
|
this.ws.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.ws.addEventListener("message", evt => {
|
||||||
|
try {
|
||||||
|
const str = evt.data.toString();
|
||||||
|
const msg = JSON.parse(str);
|
||||||
|
this.emit(msg.m, msg);
|
||||||
|
} catch (err) {
|
||||||
|
this.emit("parse_error", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
log(level, message) {
|
stop() {
|
||||||
if (!this.isConnected()) return;
|
this.started = false;
|
||||||
}
|
|
||||||
|
|
||||||
isConnected() {
|
if (this.ws) {
|
||||||
return this.ws.readyState == WebSocket.OPEN;
|
this.ws.close();
|
||||||
}
|
delete this.ws;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bindEventListeners() {
|
say(msg) {
|
||||||
this.on("log", (msg) => {
|
try {
|
||||||
console.log(`[${msg.level}] ${msg.message}`);
|
if (this.isConnected()) this.ws.send(JSON.stringify(msg));
|
||||||
});
|
return true;
|
||||||
}
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log(level, message) {
|
||||||
|
this.say({ m: "log", level, message });
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcast(msg) {
|
||||||
|
this.say({ m: "broadcast", msg });
|
||||||
|
}
|
||||||
|
|
||||||
|
isConnected() {
|
||||||
|
return this.ws.readyState == WebSocket.OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEventListeners() {
|
||||||
|
this.on("log", msg => {
|
||||||
|
console.log(`[Server] [${msg.level}] ${msg.message}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
this.say({
|
||||||
|
m: "t",
|
||||||
|
e: Date.now()
|
||||||
|
});
|
||||||
|
}, 20000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { Client };
|
module.exports = { Client };
|
||||||
|
|
24
src/index.js
24
src/index.js
|
@ -1,25 +1,25 @@
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
// TODO Make this repo a module
|
|
||||||
|
|
||||||
let isServer;
|
let isServer;
|
||||||
|
|
||||||
process.argv.forEach((val, index, array) => {
|
process.argv.forEach((val, index, array) => {
|
||||||
if (val == "client") isServer = false;
|
if (val == "client") isServer = false;
|
||||||
if (val == "server") isServer = true;
|
if (val == "server") isServer = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (typeof isServer == "undefined") {
|
if (typeof isServer == "undefined") {
|
||||||
// Incorrect arguments
|
// Incorrect arguments
|
||||||
console.log(`Usage: ${process.argv[0]} ${process.argv[1]} [client|server]`);
|
console.log(`Usage: ${process.argv[0]} ${process.argv[1]} [client|server]`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
const { Server } = require("./server");
|
const { Server } = require("./server");
|
||||||
Server.start();
|
Server.start();
|
||||||
} else {
|
} else {
|
||||||
const { Client } = require("./client");
|
const { Client } = require("./client");
|
||||||
const cl = new Client();
|
const cl = new Client();
|
||||||
cl.connect();
|
cl.connect();
|
||||||
|
|
||||||
|
cl.log("DEBUG", "hello");
|
||||||
}
|
}
|
||||||
|
|
147
src/server.js
147
src/server.js
|
@ -2,82 +2,93 @@ const WebSocket = require("ws");
|
||||||
const { EventEmitter } = require("events");
|
const { EventEmitter } = require("events");
|
||||||
|
|
||||||
function broadcast(msg) {
|
function broadcast(msg) {
|
||||||
Server.wss.clients.forEach((ws) => {
|
Server.wss.clients.forEach(ws => {
|
||||||
ws.say(msg);
|
ws.say(msg);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function log(level, message) {
|
function log(level, message) {
|
||||||
console.log(`[${level}] ${message}`);
|
console.log(`[${level}] ${message}`);
|
||||||
broadcast({ m: "log", level, message });
|
broadcast({ m: "log", level, message });
|
||||||
}
|
}
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
static start() {
|
static start() {
|
||||||
this.wss = new WebSocket.Server({
|
this.wss = new WebSocket.Server({
|
||||||
port: process.env.PORT || 10911,
|
port: process.env.PORT || 10911
|
||||||
});
|
|
||||||
|
|
||||||
this.wss.on("connection", (ws, req) => {
|
|
||||||
ws.preauth = new EventEmitter();
|
|
||||||
ws.evt = new EventEmitter();
|
|
||||||
|
|
||||||
ws.say = (msg) => {
|
|
||||||
ws.send(JSON.stringify(msg));
|
|
||||||
};
|
|
||||||
|
|
||||||
log("INFO", "Client connected at " + req.socket.remoteAddress);
|
|
||||||
|
|
||||||
ws.on("message", (data, isBinary) => {
|
|
||||||
try {
|
|
||||||
if (isBinary) return;
|
|
||||||
|
|
||||||
const str = data.toString();
|
|
||||||
const converted = JSON.parse(str);
|
|
||||||
|
|
||||||
if (converted.m) {
|
|
||||||
ws.preauth.emit(converted.m, converted);
|
|
||||||
|
|
||||||
if (ws.authed) {
|
|
||||||
ws.evt.emit(converted.m, converted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.preauth.on("hi", (msg) => {
|
|
||||||
if (!msg.project) return;
|
|
||||||
|
|
||||||
ws.authed = true;
|
|
||||||
ws.project = msg.project;
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.evt.on("log", (msg) => {
|
|
||||||
if (!msg.level) return;
|
|
||||||
if (!msg.message) return;
|
|
||||||
|
|
||||||
log(msg.level, `From ${req.socket.remoteAddress}: ${msg.message}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.evt.on("broadcast", (msg) => {
|
|
||||||
if (!msg.msg) return;
|
|
||||||
if (typeof msg.msg !== "object") return;
|
|
||||||
if (!msg.msg.m) return;
|
|
||||||
|
|
||||||
broadcast({
|
|
||||||
m: "broadcast",
|
|
||||||
msg: msg.msg,
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static stop() {
|
this.wss.on("connection", (ws, req) => {
|
||||||
this.wss.close();
|
ws.preauth = new EventEmitter();
|
||||||
delete this.wss;
|
ws.evt = new EventEmitter();
|
||||||
}
|
|
||||||
|
ws.say = msg => {
|
||||||
|
ws.send(JSON.stringify(msg));
|
||||||
|
};
|
||||||
|
|
||||||
|
log("INFO", "Client connected at " + req.socket.remoteAddress);
|
||||||
|
|
||||||
|
ws.on("message", (data, isBinary) => {
|
||||||
|
try {
|
||||||
|
if (isBinary) return;
|
||||||
|
|
||||||
|
const str = data.toString();
|
||||||
|
const converted = JSON.parse(str);
|
||||||
|
|
||||||
|
if (converted.m) {
|
||||||
|
ws.preauth.emit(converted.m, converted);
|
||||||
|
|
||||||
|
if (ws.authed) {
|
||||||
|
ws.evt.emit(converted.m, converted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.preauth.on("hi", msg => {
|
||||||
|
if (!msg.project) return;
|
||||||
|
|
||||||
|
ws.authed = true;
|
||||||
|
ws.project = msg.project;
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.evt.on("log", msg => {
|
||||||
|
if (!msg.level) return;
|
||||||
|
if (!msg.message) return;
|
||||||
|
|
||||||
|
log(
|
||||||
|
msg.level,
|
||||||
|
`From ${req.socket.remoteAddress}: ${msg.message}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.evt.on("broadcast", msg => {
|
||||||
|
if (!msg.msg) return;
|
||||||
|
if (typeof msg.msg !== "object") return;
|
||||||
|
if (!msg.msg.m) return;
|
||||||
|
|
||||||
|
broadcast({
|
||||||
|
m: "broadcast",
|
||||||
|
msg: msg.msg
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.evt.on("t", msg => {
|
||||||
|
ws.say({
|
||||||
|
m: "t",
|
||||||
|
t: Date.now(),
|
||||||
|
e: msg.e
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static stop() {
|
||||||
|
this.wss.close();
|
||||||
|
delete this.wss;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { Server };
|
module.exports = { Server };
|
||||||
|
|
Loading…
Reference in New Issue