UNPKG

uyem

Version:
235 lines 8.16 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /****************************************************************************************** * Repository: https://github.com/kolserdav/werift-sfu-react.git * File name: ws.ts * Author: Sergey Kolmiller * Email: <uyem.ru@gmail.com> * License: MIT * License text: See in LICENSE file * Copyright: kolserdav, All rights reserved (c) * Create Date: Wed Aug 24 2022 14:14:09 GMT+0700 (Krasnoyarsk Standard Time) ******************************************************************************************/ const ws_1 = require("ws"); const http_1 = require("http"); const interfaces_1 = require("../types/interfaces"); const lib_1 = require("../utils/lib"); const db_1 = __importDefault(require("./db")); const http_2 = __importDefault(require("./http")); const constants_1 = require("../utils/constants"); const server = (0, http_1.createServer)(); class WS extends db_1.default { connection; sockets = {}; delimiter = '_'; users = {}; rooms = {}; http; WebSocket = ws_1.WebSocket; constructor(connectionArgs) { const { cloudPath, prisma } = connectionArgs; super({ prisma }); this.http = new http_2.default({ prisma, cloudPath }); const _connectionArgs = { ...connectionArgs }; _connectionArgs.server = server; delete _connectionArgs.port; this.connection = this.createConnection(_connectionArgs); server.listen(connectionArgs.port); server.on('request', async (req, res) => { // CORS const headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET', 'Access-Control-Max-Age': 2592000, }; if (req.method === 'OPTIONS') { res.writeHead(204, headers); res.end(); return; } if (['GET', 'POST'].indexOf(req.method || 'GET') > -1) { Object.keys(headers).forEach((key) => { res.setHeader(key, headers[key]); }); } const { url: _url } = req; if (!_url) { res.writeHead(400); res.end(); return; } // Check token const queryString = _url.match(/\?.*$/); if (!queryString) { res.writeHead(422); res.end(); return; } const qS = queryString[0]; const url = _url.replace(qS, ''); const { [interfaces_1.TOKEN_QUERY_NAME]: token } = (0, lib_1.parseQueryString)(qS); const { errorCode, unitId } = await this.checkTokenCb({ token }); const isDefaultAuth = (0, lib_1.checkDefaultAuth)({ unitId }); if (errorCode !== 0 && !isDefaultAuth) { res.writeHead(403); res.end(); return; } const isVideos = constants_1.VIDEO_REGEX.test(url || ''); const isTmp = constants_1.TMP_REGEX.test(url || ''); if (isVideos) { await this.http.getVideoHandler({ isDefaultAuth, res, req, unitId, url, }); } else if (isTmp) { await this.http.getTmpHandler({ isDefaultAuth, res, req, unitId, url, }); } else { res.writeHead(501); res.end(); } }); } async setSocket({ id: _id, ws, connId, isRoom, userName, locale, }) { if ((0, lib_1.checkDefaultAuth)({ unitId: _id.toString() })) { return; } const oldSock = Object.keys(this.sockets).find((item) => { const sock = item.split(this.delimiter); return sock[0] === _id.toString(); }); if (oldSock) { if (this.sockets[oldSock]) { delete this.sockets[oldSock]; } } this.sockets[this.getSocketId(_id.toString(), connId)] = ws; const id = _id.toString(); if (!isRoom) { const u = await this.unitFindFirst({ where: { id, }, }); if (u) { await this.unitUpdate({ where: { id, }, data: { name: userName, updated: new Date(), }, }); } else { await this.unitCreate({ data: { id, name: userName, }, }); } this.users[id] = { connId, name: userName, locale, }; } else { this.rooms[id] = connId; } } getSocketId(id, connId) { return `${id}${this.delimiter}${connId}`; } findSocketId(id) { return Object.keys(this.sockets).find((item) => item.split(this.delimiter)[0] === id) || null; } createConnection = (args) => { this.connection = new ws_1.WebSocketServer(args); return this.connection; }; // eslint-disable-next-line class-methods-use-this parseMessage = (message) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any let data; try { data = JSON.parse(message); } catch (err) { (0, lib_1.log)('error', 'parseMessage', err); return null; } return data; }; // eslint-disable-next-line class-methods-use-this getMessage = (type, data) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const res = data; return res; }; getLocale({ userId }) { return (0, lib_1.getLocale)(this.users[userId].locale).server; } sendMessage = (args, second, cb) => new Promise((resolve) => { setTimeout(() => { let res = ''; try { res = JSON.stringify(args); } catch (e) { (0, lib_1.log)('error', 'sendMessage', e); resolve(1); } const { id } = args; (0, lib_1.log)('log', 'Send message', { id, data: args.data, type: args.type, u: this.users[id], s: Object.keys(this.sockets[this.getSocketId(id, this.users[id]?.connId)] || {}).length, r: this.rooms[id], ss: Object.keys(this.sockets[this.getSocketId(id, this.rooms[id])] || {}).length, }); let key = ''; if (this.users[id]?.connId && this.sockets[this.getSocketId(id, this.users[id]?.connId)]) { key = this.getSocketId(id, this.users[id].connId); } else if (this.rooms[id] && this.sockets[this.getSocketId(id, this.rooms[id])]) { key = this.getSocketId(id, this.rooms[id]); } if (this.sockets[key]) { this.sockets[key].send(res, cb); } else if (!second) { setTimeout(() => { this.sendMessage(args, true, cb); }, 3000); } else { (0, lib_1.log)('warn', 'Send message without conected socket', { args, }); resolve(1); } resolve(0); }, 0); }); } exports.default = WS; //# sourceMappingURL=ws.js.map