chore(cleanup): "dist" should never have been committed to git
This commit is contained in:
parent
aa9963d003
commit
04ab2a078c
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@ lib-cov
|
|||||||
*.pid
|
*.pid
|
||||||
*.gz
|
*.gz
|
||||||
|
|
||||||
|
dist
|
||||||
pids
|
pids
|
||||||
logs
|
logs
|
||||||
results
|
results
|
||||||
|
5
dist/app.json
vendored
5
dist/app.json
vendored
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "PeerJS Server",
|
|
||||||
"description": "A server side element to broker connections between PeerJS clients.",
|
|
||||||
"website": "https://peerjs.com/"
|
|
||||||
}
|
|
26
dist/src/api/index.js
vendored
26
dist/src/api/index.js
vendored
@ -1,26 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Api = void 0;
|
|
||||||
const body_parser_1 = __importDefault(require("body-parser"));
|
|
||||||
const cors_1 = __importDefault(require("cors"));
|
|
||||||
const express_1 = __importDefault(require("express"));
|
|
||||||
const app_json_1 = __importDefault(require("../../app.json"));
|
|
||||||
const auth_1 = require("./middleware/auth");
|
|
||||||
const calls_1 = __importDefault(require("./v1/calls"));
|
|
||||||
const public_1 = __importDefault(require("./v1/public"));
|
|
||||||
const Api = ({ config, realm, messageHandler }) => {
|
|
||||||
const authMiddleware = new auth_1.AuthMiddleware(config, realm);
|
|
||||||
const app = express_1.default.Router();
|
|
||||||
const jsonParser = body_parser_1.default.json();
|
|
||||||
app.use(cors_1.default());
|
|
||||||
app.get("/", (_, res) => {
|
|
||||||
res.send(app_json_1.default);
|
|
||||||
});
|
|
||||||
app.use("/:key", public_1.default({ config, realm }));
|
|
||||||
app.use("/:key/:id/:token", authMiddleware.handle, jsonParser, calls_1.default({ realm, messageHandler }));
|
|
||||||
return app;
|
|
||||||
};
|
|
||||||
exports.Api = Api;
|
|
28
dist/src/api/middleware/auth/index.js
vendored
28
dist/src/api/middleware/auth/index.js
vendored
@ -1,28 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.AuthMiddleware = void 0;
|
|
||||||
const enums_1 = require("../../../enums");
|
|
||||||
class AuthMiddleware {
|
|
||||||
constructor(config, realm) {
|
|
||||||
this.config = config;
|
|
||||||
this.realm = realm;
|
|
||||||
this.handle = (req, res, next) => {
|
|
||||||
const { id, token, key } = req.params;
|
|
||||||
if (key !== this.config.key) {
|
|
||||||
return res.status(401).send(enums_1.Errors.INVALID_KEY);
|
|
||||||
}
|
|
||||||
if (!id) {
|
|
||||||
return res.sendStatus(401);
|
|
||||||
}
|
|
||||||
const client = this.realm.getClientById(id);
|
|
||||||
if (!client) {
|
|
||||||
return res.sendStatus(401);
|
|
||||||
}
|
|
||||||
if (client.getToken() && token !== client.getToken()) {
|
|
||||||
return res.status(401).send(enums_1.Errors.INVALID_TOKEN);
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.AuthMiddleware = AuthMiddleware;
|
|
2
dist/src/api/middleware/middleware.js
vendored
2
dist/src/api/middleware/middleware.js
vendored
@ -1,2 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
dist/src/api/v1/calls/index.js
vendored
32
dist/src/api/v1/calls/index.js
vendored
@ -1,32 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const express_1 = __importDefault(require("express"));
|
|
||||||
exports.default = ({ realm, messageHandler }) => {
|
|
||||||
const app = express_1.default.Router();
|
|
||||||
const handle = (req, res, next) => {
|
|
||||||
const { id } = req.params;
|
|
||||||
if (!id)
|
|
||||||
return next();
|
|
||||||
const client = realm.getClientById(id);
|
|
||||||
if (!client) {
|
|
||||||
throw new Error(`client not found:${id}`);
|
|
||||||
}
|
|
||||||
const { type, dst, payload } = req.body;
|
|
||||||
const message = {
|
|
||||||
type,
|
|
||||||
src: id,
|
|
||||||
dst,
|
|
||||||
payload
|
|
||||||
};
|
|
||||||
messageHandler.handle(client, message);
|
|
||||||
res.sendStatus(200);
|
|
||||||
};
|
|
||||||
app.post("/offer", handle);
|
|
||||||
app.post("/candidate", handle);
|
|
||||||
app.post("/answer", handle);
|
|
||||||
app.post("/leave", handle);
|
|
||||||
return app;
|
|
||||||
};
|
|
23
dist/src/api/v1/public/index.js
vendored
23
dist/src/api/v1/public/index.js
vendored
@ -1,23 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const express_1 = __importDefault(require("express"));
|
|
||||||
exports.default = ({ config, realm }) => {
|
|
||||||
const app = express_1.default.Router();
|
|
||||||
// Retrieve guaranteed random ID.
|
|
||||||
app.get("/id", (_, res) => {
|
|
||||||
res.contentType("html");
|
|
||||||
res.send(realm.generateClientId(config.generateClientId));
|
|
||||||
});
|
|
||||||
// Get a list of all peers for a key, enabled by the `allowDiscovery` flag.
|
|
||||||
app.get("/peers", (_, res) => {
|
|
||||||
if (config.allow_discovery) {
|
|
||||||
const clientsIds = realm.getClientsIds();
|
|
||||||
return res.send(clientsIds);
|
|
||||||
}
|
|
||||||
res.sendStatus(401);
|
|
||||||
});
|
|
||||||
return app;
|
|
||||||
};
|
|
15
dist/src/config/index.js
vendored
15
dist/src/config/index.js
vendored
@ -1,15 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const defaultConfig = {
|
|
||||||
host: "::",
|
|
||||||
port: 9000,
|
|
||||||
expire_timeout: 5000,
|
|
||||||
alive_timeout: 60000,
|
|
||||||
key: "peerjs",
|
|
||||||
path: "/",
|
|
||||||
concurrent_limit: 5000,
|
|
||||||
allow_discovery: false,
|
|
||||||
proxied: false,
|
|
||||||
cleanup_out_msgs: 1000,
|
|
||||||
};
|
|
||||||
exports.default = defaultConfig;
|
|
22
dist/src/enums.js
vendored
22
dist/src/enums.js
vendored
@ -1,22 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.MessageType = exports.Errors = void 0;
|
|
||||||
var Errors;
|
|
||||||
(function (Errors) {
|
|
||||||
Errors["INVALID_KEY"] = "Invalid key provided";
|
|
||||||
Errors["INVALID_TOKEN"] = "Invalid token provided";
|
|
||||||
Errors["INVALID_WS_PARAMETERS"] = "No id, token, or key supplied to websocket server";
|
|
||||||
Errors["CONNECTION_LIMIT_EXCEED"] = "Server has reached its concurrent user limit";
|
|
||||||
})(Errors = exports.Errors || (exports.Errors = {}));
|
|
||||||
var MessageType;
|
|
||||||
(function (MessageType) {
|
|
||||||
MessageType["OPEN"] = "OPEN";
|
|
||||||
MessageType["LEAVE"] = "LEAVE";
|
|
||||||
MessageType["CANDIDATE"] = "CANDIDATE";
|
|
||||||
MessageType["OFFER"] = "OFFER";
|
|
||||||
MessageType["ANSWER"] = "ANSWER";
|
|
||||||
MessageType["EXPIRE"] = "EXPIRE";
|
|
||||||
MessageType["HEARTBEAT"] = "HEARTBEAT";
|
|
||||||
MessageType["ID_TAKEN"] = "ID-TAKEN";
|
|
||||||
MessageType["ERROR"] = "ERROR";
|
|
||||||
})(MessageType = exports.MessageType || (exports.MessageType = {}));
|
|
58
dist/src/index.js
vendored
58
dist/src/index.js
vendored
@ -1,58 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __rest = (this && this.__rest) || function (s, e) {
|
|
||||||
var t = {};
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
||||||
t[p] = s[p];
|
|
||||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
||||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
||||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
||||||
t[p[i]] = s[p[i]];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.PeerServer = exports.ExpressPeerServer = void 0;
|
|
||||||
const express_1 = __importDefault(require("express"));
|
|
||||||
const http_1 = __importDefault(require("http"));
|
|
||||||
const https_1 = __importDefault(require("https"));
|
|
||||||
const config_1 = __importDefault(require("./config"));
|
|
||||||
const instance_1 = require("./instance");
|
|
||||||
function ExpressPeerServer(server, options) {
|
|
||||||
const app = express_1.default();
|
|
||||||
const newOptions = Object.assign(Object.assign({}, config_1.default), options);
|
|
||||||
if (newOptions.proxied) {
|
|
||||||
app.set("trust proxy", newOptions.proxied === "false" ? false : !!newOptions.proxied);
|
|
||||||
}
|
|
||||||
app.on("mount", () => {
|
|
||||||
if (!server) {
|
|
||||||
throw new Error("Server is not passed to constructor - " +
|
|
||||||
"can't start PeerServer");
|
|
||||||
}
|
|
||||||
instance_1.createInstance({ app, server, options: newOptions });
|
|
||||||
});
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
exports.ExpressPeerServer = ExpressPeerServer;
|
|
||||||
function PeerServer(options = {}, callback) {
|
|
||||||
const app = express_1.default();
|
|
||||||
let newOptions = Object.assign(Object.assign({}, config_1.default), options);
|
|
||||||
const port = newOptions.port;
|
|
||||||
const host = newOptions.host;
|
|
||||||
let server;
|
|
||||||
const { ssl } = newOptions, restOptions = __rest(newOptions, ["ssl"]);
|
|
||||||
if (ssl && Object.keys(ssl).length) {
|
|
||||||
server = https_1.default.createServer(ssl, app);
|
|
||||||
newOptions = restOptions;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
server = http_1.default.createServer(app);
|
|
||||||
}
|
|
||||||
const peerjs = ExpressPeerServer(server, newOptions);
|
|
||||||
app.use(peerjs);
|
|
||||||
server.listen(port, host, () => callback === null || callback === void 0 ? void 0 : callback(server));
|
|
||||||
return peerjs;
|
|
||||||
}
|
|
||||||
exports.PeerServer = PeerServer;
|
|
59
dist/src/instance.js
vendored
59
dist/src/instance.js
vendored
@ -1,59 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.createInstance = void 0;
|
|
||||||
const path_1 = __importDefault(require("path"));
|
|
||||||
const realm_1 = require("./models/realm");
|
|
||||||
const checkBrokenConnections_1 = require("./services/checkBrokenConnections");
|
|
||||||
const messagesExpire_1 = require("./services/messagesExpire");
|
|
||||||
const webSocketServer_1 = require("./services/webSocketServer");
|
|
||||||
const messageHandler_1 = require("./messageHandler");
|
|
||||||
const api_1 = require("./api");
|
|
||||||
const createInstance = ({ app, server, options }) => {
|
|
||||||
const config = options;
|
|
||||||
const realm = new realm_1.Realm();
|
|
||||||
const messageHandler = new messageHandler_1.MessageHandler(realm);
|
|
||||||
const api = api_1.Api({ config, realm, messageHandler });
|
|
||||||
const messagesExpire = new messagesExpire_1.MessagesExpire({ realm, config, messageHandler });
|
|
||||||
const checkBrokenConnections = new checkBrokenConnections_1.CheckBrokenConnections({
|
|
||||||
realm,
|
|
||||||
config,
|
|
||||||
onClose: client => {
|
|
||||||
app.emit("disconnect", client);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
app.use(options.path, api);
|
|
||||||
//use mountpath for WS server
|
|
||||||
const customConfig = Object.assign(Object.assign({}, config), { path: path_1.default.posix.join(app.path(), options.path, '/') });
|
|
||||||
const wss = new webSocketServer_1.WebSocketServer({
|
|
||||||
server,
|
|
||||||
realm,
|
|
||||||
config: customConfig
|
|
||||||
});
|
|
||||||
wss.on("connection", (client) => {
|
|
||||||
const messageQueue = realm.getMessageQueueById(client.getId());
|
|
||||||
if (messageQueue) {
|
|
||||||
let message;
|
|
||||||
while ((message = messageQueue.readMessage())) {
|
|
||||||
messageHandler.handle(client, message);
|
|
||||||
}
|
|
||||||
realm.clearMessageQueue(client.getId());
|
|
||||||
}
|
|
||||||
app.emit("connection", client);
|
|
||||||
});
|
|
||||||
wss.on("message", (client, message) => {
|
|
||||||
app.emit("message", client, message);
|
|
||||||
messageHandler.handle(client, message);
|
|
||||||
});
|
|
||||||
wss.on("close", (client) => {
|
|
||||||
app.emit("disconnect", client);
|
|
||||||
});
|
|
||||||
wss.on("error", (error) => {
|
|
||||||
app.emit("error", error);
|
|
||||||
});
|
|
||||||
messagesExpire.startMessagesExpiration();
|
|
||||||
checkBrokenConnections.start();
|
|
||||||
};
|
|
||||||
exports.createInstance = createInstance;
|
|
2
dist/src/messageHandler/handler.js
vendored
2
dist/src/messageHandler/handler.js
vendored
@ -1,2 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@ -1,11 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.HeartbeatHandler = void 0;
|
|
||||||
const HeartbeatHandler = (client) => {
|
|
||||||
if (client) {
|
|
||||||
const nowTime = new Date().getTime();
|
|
||||||
client.setLastPing(nowTime);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
exports.HeartbeatHandler = HeartbeatHandler;
|
|
7
dist/src/messageHandler/handlers/index.js
vendored
7
dist/src/messageHandler/handlers/index.js
vendored
@ -1,7 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.TransmissionHandler = exports.HeartbeatHandler = void 0;
|
|
||||||
var heartbeat_1 = require("./heartbeat");
|
|
||||||
Object.defineProperty(exports, "HeartbeatHandler", { enumerable: true, get: function () { return heartbeat_1.HeartbeatHandler; } });
|
|
||||||
var transmission_1 = require("./transmission");
|
|
||||||
Object.defineProperty(exports, "TransmissionHandler", { enumerable: true, get: function () { return transmission_1.TransmissionHandler; } });
|
|
@ -1,60 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.TransmissionHandler = void 0;
|
|
||||||
const enums_1 = require("../../../enums");
|
|
||||||
const TransmissionHandler = ({ realm }) => {
|
|
||||||
const handle = (client, message) => {
|
|
||||||
const type = message.type;
|
|
||||||
const srcId = message.src;
|
|
||||||
const dstId = message.dst;
|
|
||||||
const destinationClient = realm.getClientById(dstId);
|
|
||||||
// User is connected!
|
|
||||||
if (destinationClient) {
|
|
||||||
const socket = destinationClient.getSocket();
|
|
||||||
try {
|
|
||||||
if (socket) {
|
|
||||||
const data = JSON.stringify(message);
|
|
||||||
socket.send(data);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Neither socket no res available. Peer dead?
|
|
||||||
throw new Error("Peer dead");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
// This happens when a peer disconnects without closing connections and
|
|
||||||
// the associated WebSocket has not closed.
|
|
||||||
// Tell other side to stop trying.
|
|
||||||
if (socket) {
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
realm.removeClientById(destinationClient.getId());
|
|
||||||
}
|
|
||||||
handle(client, {
|
|
||||||
type: enums_1.MessageType.LEAVE,
|
|
||||||
src: dstId,
|
|
||||||
dst: srcId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Wait for this client to connect/reconnect (XHR) for important
|
|
||||||
// messages.
|
|
||||||
const ignoredTypes = [enums_1.MessageType.LEAVE, enums_1.MessageType.EXPIRE];
|
|
||||||
if (!ignoredTypes.includes(type) && dstId) {
|
|
||||||
realm.addMessageToQueue(dstId, message);
|
|
||||||
}
|
|
||||||
else if (type === enums_1.MessageType.LEAVE && !dstId) {
|
|
||||||
realm.removeClientById(srcId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Unavailable destination specified with message LEAVE or EXPIRE
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
return handle;
|
|
||||||
};
|
|
||||||
exports.TransmissionHandler = TransmissionHandler;
|
|
21
dist/src/messageHandler/handlersRegistry.js
vendored
21
dist/src/messageHandler/handlersRegistry.js
vendored
@ -1,21 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.HandlersRegistry = void 0;
|
|
||||||
class HandlersRegistry {
|
|
||||||
constructor() {
|
|
||||||
this.handlers = new Map();
|
|
||||||
}
|
|
||||||
registerHandler(messageType, handler) {
|
|
||||||
if (this.handlers.has(messageType))
|
|
||||||
return;
|
|
||||||
this.handlers.set(messageType, handler);
|
|
||||||
}
|
|
||||||
handle(client, message) {
|
|
||||||
const { type } = message;
|
|
||||||
const handler = this.handlers.get(type);
|
|
||||||
if (!handler)
|
|
||||||
return false;
|
|
||||||
return handler(client, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.HandlersRegistry = HandlersRegistry;
|
|
32
dist/src/messageHandler/index.js
vendored
32
dist/src/messageHandler/index.js
vendored
@ -1,32 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.MessageHandler = void 0;
|
|
||||||
const enums_1 = require("../enums");
|
|
||||||
const handlers_1 = require("./handlers");
|
|
||||||
const handlersRegistry_1 = require("./handlersRegistry");
|
|
||||||
class MessageHandler {
|
|
||||||
constructor(realm, handlersRegistry = new handlersRegistry_1.HandlersRegistry()) {
|
|
||||||
this.handlersRegistry = handlersRegistry;
|
|
||||||
const transmissionHandler = handlers_1.TransmissionHandler({ realm });
|
|
||||||
const heartbeatHandler = handlers_1.HeartbeatHandler;
|
|
||||||
const handleTransmission = (client, { type, src, dst, payload }) => {
|
|
||||||
return transmissionHandler(client, {
|
|
||||||
type,
|
|
||||||
src,
|
|
||||||
dst,
|
|
||||||
payload,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleHeartbeat = (client, message) => heartbeatHandler(client, message);
|
|
||||||
this.handlersRegistry.registerHandler(enums_1.MessageType.HEARTBEAT, handleHeartbeat);
|
|
||||||
this.handlersRegistry.registerHandler(enums_1.MessageType.OFFER, handleTransmission);
|
|
||||||
this.handlersRegistry.registerHandler(enums_1.MessageType.ANSWER, handleTransmission);
|
|
||||||
this.handlersRegistry.registerHandler(enums_1.MessageType.CANDIDATE, handleTransmission);
|
|
||||||
this.handlersRegistry.registerHandler(enums_1.MessageType.LEAVE, handleTransmission);
|
|
||||||
this.handlersRegistry.registerHandler(enums_1.MessageType.EXPIRE, handleTransmission);
|
|
||||||
}
|
|
||||||
handle(client, message) {
|
|
||||||
return this.handlersRegistry.handle(client, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.MessageHandler = MessageHandler;
|
|
34
dist/src/models/client.js
vendored
34
dist/src/models/client.js
vendored
@ -1,34 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Client = void 0;
|
|
||||||
class Client {
|
|
||||||
constructor({ id, token }) {
|
|
||||||
this.socket = null;
|
|
||||||
this.lastPing = new Date().getTime();
|
|
||||||
this.id = id;
|
|
||||||
this.token = token;
|
|
||||||
}
|
|
||||||
getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
getToken() {
|
|
||||||
return this.token;
|
|
||||||
}
|
|
||||||
getSocket() {
|
|
||||||
return this.socket;
|
|
||||||
}
|
|
||||||
setSocket(socket) {
|
|
||||||
this.socket = socket;
|
|
||||||
}
|
|
||||||
getLastPing() {
|
|
||||||
return this.lastPing;
|
|
||||||
}
|
|
||||||
setLastPing(lastPing) {
|
|
||||||
this.lastPing = lastPing;
|
|
||||||
}
|
|
||||||
send(data) {
|
|
||||||
var _a;
|
|
||||||
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.Client = Client;
|
|
2
dist/src/models/message.js
vendored
2
dist/src/models/message.js
vendored
@ -1,2 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
dist/src/models/messageQueue.js
vendored
26
dist/src/models/messageQueue.js
vendored
@ -1,26 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.MessageQueue = void 0;
|
|
||||||
class MessageQueue {
|
|
||||||
constructor() {
|
|
||||||
this.lastReadAt = new Date().getTime();
|
|
||||||
this.messages = [];
|
|
||||||
}
|
|
||||||
getLastReadAt() {
|
|
||||||
return this.lastReadAt;
|
|
||||||
}
|
|
||||||
addMessage(message) {
|
|
||||||
this.messages.push(message);
|
|
||||||
}
|
|
||||||
readMessage() {
|
|
||||||
if (this.messages.length > 0) {
|
|
||||||
this.lastReadAt = new Date().getTime();
|
|
||||||
return this.messages.shift();
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
getMessages() {
|
|
||||||
return this.messages;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.MessageQueue = MessageQueue;
|
|
55
dist/src/models/realm.js
vendored
55
dist/src/models/realm.js
vendored
@ -1,55 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Realm = void 0;
|
|
||||||
const v4_1 = __importDefault(require("uuid/v4"));
|
|
||||||
const messageQueue_1 = require("./messageQueue");
|
|
||||||
class Realm {
|
|
||||||
constructor() {
|
|
||||||
this.clients = new Map();
|
|
||||||
this.messageQueues = new Map();
|
|
||||||
}
|
|
||||||
getClientsIds() {
|
|
||||||
return [...this.clients.keys()];
|
|
||||||
}
|
|
||||||
getClientById(clientId) {
|
|
||||||
return this.clients.get(clientId);
|
|
||||||
}
|
|
||||||
getClientsIdsWithQueue() {
|
|
||||||
return [...this.messageQueues.keys()];
|
|
||||||
}
|
|
||||||
setClient(client, id) {
|
|
||||||
this.clients.set(id, client);
|
|
||||||
}
|
|
||||||
removeClientById(id) {
|
|
||||||
const client = this.getClientById(id);
|
|
||||||
if (!client)
|
|
||||||
return false;
|
|
||||||
this.clients.delete(id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
getMessageQueueById(id) {
|
|
||||||
return this.messageQueues.get(id);
|
|
||||||
}
|
|
||||||
addMessageToQueue(id, message) {
|
|
||||||
var _a;
|
|
||||||
if (!this.getMessageQueueById(id)) {
|
|
||||||
this.messageQueues.set(id, new messageQueue_1.MessageQueue());
|
|
||||||
}
|
|
||||||
(_a = this.getMessageQueueById(id)) === null || _a === void 0 ? void 0 : _a.addMessage(message);
|
|
||||||
}
|
|
||||||
clearMessageQueue(id) {
|
|
||||||
this.messageQueues.delete(id);
|
|
||||||
}
|
|
||||||
generateClientId(generateClientId) {
|
|
||||||
const generateId = generateClientId ? generateClientId : v4_1.default;
|
|
||||||
let clientId = generateId();
|
|
||||||
while (this.getClientById(clientId)) {
|
|
||||||
clientId = generateId();
|
|
||||||
}
|
|
||||||
return clientId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.Realm = Realm;
|
|
@ -1,53 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.CheckBrokenConnections = void 0;
|
|
||||||
const DEFAULT_CHECK_INTERVAL = 300;
|
|
||||||
class CheckBrokenConnections {
|
|
||||||
constructor({ realm, config, checkInterval = DEFAULT_CHECK_INTERVAL, onClose }) {
|
|
||||||
this.timeoutId = null;
|
|
||||||
this.realm = realm;
|
|
||||||
this.config = config;
|
|
||||||
this.onClose = onClose;
|
|
||||||
this.checkInterval = checkInterval;
|
|
||||||
}
|
|
||||||
start() {
|
|
||||||
if (this.timeoutId) {
|
|
||||||
clearTimeout(this.timeoutId);
|
|
||||||
}
|
|
||||||
this.timeoutId = setTimeout(() => {
|
|
||||||
this.checkConnections();
|
|
||||||
this.timeoutId = null;
|
|
||||||
this.start();
|
|
||||||
}, this.checkInterval);
|
|
||||||
}
|
|
||||||
stop() {
|
|
||||||
if (this.timeoutId) {
|
|
||||||
clearTimeout(this.timeoutId);
|
|
||||||
this.timeoutId = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkConnections() {
|
|
||||||
var _a, _b;
|
|
||||||
const clientsIds = this.realm.getClientsIds();
|
|
||||||
const now = new Date().getTime();
|
|
||||||
const { alive_timeout: aliveTimeout } = this.config;
|
|
||||||
for (const clientId of clientsIds) {
|
|
||||||
const client = this.realm.getClientById(clientId);
|
|
||||||
if (!client)
|
|
||||||
continue;
|
|
||||||
const timeSinceLastPing = now - client.getLastPing();
|
|
||||||
if (timeSinceLastPing < aliveTimeout)
|
|
||||||
continue;
|
|
||||||
try {
|
|
||||||
(_a = client.getSocket()) === null || _a === void 0 ? void 0 : _a.close();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
this.realm.clearMessageQueue(clientId);
|
|
||||||
this.realm.removeClientById(clientId);
|
|
||||||
client.setSocket(null);
|
|
||||||
(_b = this.onClose) === null || _b === void 0 ? void 0 : _b.call(this, client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.CheckBrokenConnections = CheckBrokenConnections;
|
|
57
dist/src/services/messagesExpire/index.js
vendored
57
dist/src/services/messagesExpire/index.js
vendored
@ -1,57 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.MessagesExpire = void 0;
|
|
||||||
const enums_1 = require("../../enums");
|
|
||||||
class MessagesExpire {
|
|
||||||
constructor({ realm, config, messageHandler }) {
|
|
||||||
this.timeoutId = null;
|
|
||||||
this.realm = realm;
|
|
||||||
this.config = config;
|
|
||||||
this.messageHandler = messageHandler;
|
|
||||||
}
|
|
||||||
startMessagesExpiration() {
|
|
||||||
if (this.timeoutId) {
|
|
||||||
clearTimeout(this.timeoutId);
|
|
||||||
}
|
|
||||||
// Clean up outstanding messages
|
|
||||||
this.timeoutId = setTimeout(() => {
|
|
||||||
this.pruneOutstanding();
|
|
||||||
this.timeoutId = null;
|
|
||||||
this.startMessagesExpiration();
|
|
||||||
}, this.config.cleanup_out_msgs);
|
|
||||||
}
|
|
||||||
stopMessagesExpiration() {
|
|
||||||
if (this.timeoutId) {
|
|
||||||
clearTimeout(this.timeoutId);
|
|
||||||
this.timeoutId = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pruneOutstanding() {
|
|
||||||
const destinationClientsIds = this.realm.getClientsIdsWithQueue();
|
|
||||||
const now = new Date().getTime();
|
|
||||||
const maxDiff = this.config.expire_timeout;
|
|
||||||
const seen = {};
|
|
||||||
for (const destinationClientId of destinationClientsIds) {
|
|
||||||
const messageQueue = this.realm.getMessageQueueById(destinationClientId);
|
|
||||||
if (!messageQueue)
|
|
||||||
continue;
|
|
||||||
const lastReadDiff = now - messageQueue.getLastReadAt();
|
|
||||||
if (lastReadDiff < maxDiff)
|
|
||||||
continue;
|
|
||||||
const messages = messageQueue.getMessages();
|
|
||||||
for (const message of messages) {
|
|
||||||
const seenKey = `${message.src}_${message.dst}`;
|
|
||||||
if (!seen[seenKey]) {
|
|
||||||
this.messageHandler.handle(undefined, {
|
|
||||||
type: enums_1.MessageType.EXPIRE,
|
|
||||||
src: message.dst,
|
|
||||||
dst: message.src
|
|
||||||
});
|
|
||||||
seen[seenKey] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.realm.clearMessageQueue(destinationClientId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.MessagesExpire = MessagesExpire;
|
|
94
dist/src/services/webSocketServer/index.js
vendored
94
dist/src/services/webSocketServer/index.js
vendored
@ -1,94 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.WebSocketServer = void 0;
|
|
||||||
const events_1 = __importDefault(require("events"));
|
|
||||||
const url_1 = __importDefault(require("url"));
|
|
||||||
const ws_1 = __importDefault(require("ws"));
|
|
||||||
const enums_1 = require("../../enums");
|
|
||||||
const client_1 = require("../../models/client");
|
|
||||||
const WS_PATH = 'peerjs';
|
|
||||||
class WebSocketServer extends events_1.default {
|
|
||||||
constructor({ server, realm, config }) {
|
|
||||||
super();
|
|
||||||
this.setMaxListeners(0);
|
|
||||||
this.realm = realm;
|
|
||||||
this.config = config;
|
|
||||||
const path = this.config.path;
|
|
||||||
this.path = `${path}${path.endsWith('/') ? "" : "/"}${WS_PATH}`;
|
|
||||||
this.socketServer = new ws_1.default.Server({ path: this.path, server });
|
|
||||||
this.socketServer.on("connection", (socket, req) => this._onSocketConnection(socket, req));
|
|
||||||
this.socketServer.on("error", (error) => this._onSocketError(error));
|
|
||||||
}
|
|
||||||
_onSocketConnection(socket, req) {
|
|
||||||
var _a;
|
|
||||||
const { query = {} } = url_1.default.parse((_a = req.url) !== null && _a !== void 0 ? _a : '', true);
|
|
||||||
const { id, token, key } = query;
|
|
||||||
if (!id || !token || !key) {
|
|
||||||
return this._sendErrorAndClose(socket, enums_1.Errors.INVALID_WS_PARAMETERS);
|
|
||||||
}
|
|
||||||
if (key !== this.config.key) {
|
|
||||||
return this._sendErrorAndClose(socket, enums_1.Errors.INVALID_KEY);
|
|
||||||
}
|
|
||||||
const client = this.realm.getClientById(id);
|
|
||||||
if (client) {
|
|
||||||
if (token !== client.getToken()) {
|
|
||||||
// ID-taken, invalid token
|
|
||||||
socket.send(JSON.stringify({
|
|
||||||
type: enums_1.MessageType.ID_TAKEN,
|
|
||||||
payload: { msg: "ID is taken" }
|
|
||||||
}));
|
|
||||||
return socket.close();
|
|
||||||
}
|
|
||||||
return this._configureWS(socket, client);
|
|
||||||
}
|
|
||||||
this._registerClient({ socket, id, token });
|
|
||||||
}
|
|
||||||
_onSocketError(error) {
|
|
||||||
// handle error
|
|
||||||
this.emit("error", error);
|
|
||||||
}
|
|
||||||
_registerClient({ socket, id, token }) {
|
|
||||||
// Check concurrent limit
|
|
||||||
const clientsCount = this.realm.getClientsIds().length;
|
|
||||||
if (clientsCount >= this.config.concurrent_limit) {
|
|
||||||
return this._sendErrorAndClose(socket, enums_1.Errors.CONNECTION_LIMIT_EXCEED);
|
|
||||||
}
|
|
||||||
const newClient = new client_1.Client({ id, token });
|
|
||||||
this.realm.setClient(newClient, id);
|
|
||||||
socket.send(JSON.stringify({ type: enums_1.MessageType.OPEN }));
|
|
||||||
this._configureWS(socket, newClient);
|
|
||||||
}
|
|
||||||
_configureWS(socket, client) {
|
|
||||||
client.setSocket(socket);
|
|
||||||
// Cleanup after a socket closes.
|
|
||||||
socket.on("close", () => {
|
|
||||||
if (client.getSocket() === socket) {
|
|
||||||
this.realm.removeClientById(client.getId());
|
|
||||||
this.emit("close", client);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Handle messages from peers.
|
|
||||||
socket.on("message", (data) => {
|
|
||||||
try {
|
|
||||||
const message = JSON.parse(data);
|
|
||||||
message.src = client.getId();
|
|
||||||
this.emit("message", client, message);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
this.emit("error", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.emit("connection", client);
|
|
||||||
}
|
|
||||||
_sendErrorAndClose(socket, msg) {
|
|
||||||
socket.send(JSON.stringify({
|
|
||||||
type: enums_1.MessageType.ERROR,
|
|
||||||
payload: { msg }
|
|
||||||
}));
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.WebSocketServer = WebSocketServer;
|
|
@ -1,2 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
Loading…
x
Reference in New Issue
Block a user