UNPKG

tgrid

Version:

Grid Computing Framework for TypeScript

250 lines 12.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; 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 (g && (g = 0, op[0] && (_ = 0)), _) 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 }; } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebSocketServer = void 0; var tstl_1 = require("tstl"); var NodeModule_1 = require("../../utils/internal/NodeModule"); var WebSocketAcceptor_1 = require("./WebSocketAcceptor"); /** * Web Socket Server. * * - available only in the NodeJS. * * The `WebSocketServer` is a class who can open an websocket server. Clients * connecting to the `WebSocketServer` would communicate with this websocket server * through {@link WebSocketAcceptor} instances with RPC (Remote Procedure Call) * concept. * * To open the websocket server, call the {@link open} method with your callback * function which would be called whenever a {@link WebSocketAcceptor} has been * newly created by a new client's connection. * * Also, when declaring this {@link WebSocketServer} type, you have to define three * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments * would be propagated to the {@link WebSocketAcceptor}, so that * {@link WebSocketAcceptor} would have the same generic arguments, too. * * For reference, the first `Header` type represents an initial data from the * remote client after the connection. I recommend utilize it as an activation tool * for security enhancement. The second generic argument `Provider` represents a * provider from server to client, and the other `Remote` means a provider from the * remote client to server. * * @template Header Type of header containing initialization data like activation. * @template Provider Type of features provided for the remote client. * @template Remote Type of features provided by remote client. * @author Jeongho Nam - https://github.com/samchon */ var WebSocketServer = /** @class */ (function () { function WebSocketServer(key, cert) { if ((0, tstl_1.is_node)() === false) throw new Error("Error on WebSocketServer.constructor(): only available in NodeJS."); // PREPARE SERVER INSTANCE this.options_ = !!key && !!cert ? { key: key, cert: cert } : null; // INITIALIZE STATUS & PROTOCOL this.state_ = -1 /* WebSocketServer.State.NONE */; this.server_ = null; this.protocol_ = null; } /** * Open websocket server. * * Open a server through the web-socket protocol, with its *port* number and *handler* * function determining whether to accept the client's connection or not. After the server has * been opened, clients can connect to that websocket server by using the {@link WebSocketConnector} * class. * * When implementing the *handler* function with the {@link WebSocketAcceptor} instance, calls the * {@link WebSocketAcceptor.accept} method if you want to accept the new client's connection. * Otherwise you don't want to accept the client and reject its connection, just calls the * {@link WebSocketAcceptor.reject} instead. * * @param port Port number to listen. * @param handler Callback function for client connection. */ WebSocketServer.prototype.open = function (port, handler) { return __awaiter(this, void 0, void 0, function () { var _a, _b, _c; var _this = this; return __generator(this, function (_d) { switch (_d.label) { case 0: if (!(this.state_ === 1 /* WebSocketServer.State.OPEN */)) return [3 /*break*/, 1]; throw new Error("Error on WebSocketServer.open(): it has already been opened."); case 1: if (!(this.state_ === 0 /* WebSocketServer.State.OPENING */)) return [3 /*break*/, 2]; throw new Error("Error on WebSocketServer.open(): it's on opening, wait for a second."); case 2: if (!(this.state_ === 2 /* WebSocketServer.State.CLOSING */)) return [3 /*break*/, 3]; throw new Error("Error on WebSocketServer.open(): it's on closing."); case 3: if (!(this.server_ === null || this.state_ === 3 /* WebSocketServer.State.CLOSED */)) return [3 /*break*/, 8]; _a = this; if (!(this.options_ !== null)) return [3 /*break*/, 5]; return [4 /*yield*/, NodeModule_1.NodeModule.https.get()]; case 4: _b = (_d.sent()).createServer(this.options_); return [3 /*break*/, 7]; case 5: return [4 /*yield*/, NodeModule_1.NodeModule.http.get()]; case 6: _b = (_d.sent()).createServer(); _d.label = 7; case 7: _a.server_ = _b; _d.label = 8; case 8: _c = this; return [4 /*yield*/, NodeModule_1.NodeModule.ws.get()]; case 9: _c.protocol_ = new (_d.sent()).default.Server({ noServer: true, }); // SET STATE this.state_ = 0 /* WebSocketServer.State.OPENING */; //---- // OPEN SERVER //---- // PROTOCOL - ADAPTOR & ACCEPTOR this.server_.on("upgrade", function (request, netSocket, header) { _this.protocol_.handleUpgrade(request, netSocket, header, function (socket) { return WebSocketAcceptor_1.WebSocketAcceptor.upgrade(request, socket, handler); }); }); // FINALIZATION return [4 /*yield*/, WebSocketServer._Open(this.server_, port, function (state) { return (_this.state_ = state); })]; case 10: // FINALIZATION _d.sent(); return [2 /*return*/]; } }); }); }; /** * Close server. * * Close all connections between its remote clients ({@link WebSocketConnector}s). * * It destroys all RFCs (remote function calls) between this server and remote clients * (through `Driver<Controller>`) that are not returned (completed) yet. The destruction * causes all incomplete RFCs to throw exceptions. */ WebSocketServer.prototype.close = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: // VALIDATION if (this.state_ !== 1 /* WebSocketServer.State.OPEN */) throw new Error("Error on WebSocketServer.close(): server is not opened."); // DO CLOSE this.state_ = 2 /* WebSocketServer.State.CLOSING */; return [4 /*yield*/, this._Close()]; case 1: _a.sent(); this.state_ = 3 /* WebSocketServer.State.CLOSED */; return [2 /*return*/]; } }); }); }; /** * @hidden */ WebSocketServer._Open = function (server, port, setState) { return new Promise(function (resolve, reject) { // PREPARE RETURNS server.on("listening", function () { setState(1 /* WebSocketServer.State.OPEN */); server.on("error", function () { }); resolve(); }); server.on("error", function (error) { setState(-1 /* WebSocketServer.State.NONE */); reject(error); }); // DO OPEN - START PROVIDE server.listen(port); }); }; /** * @hidden */ WebSocketServer.prototype._Close = function () { var _this = this; return new Promise(function (resolve) { _this.protocol_.close(function () { _this.server_.close(function () { resolve(); }); }); }); }; Object.defineProperty(WebSocketServer.prototype, "state", { /* ---------------------------------------------------------------- ACCESSORS ---------------------------------------------------------------- */ /** * Get server state. * * Get current state of the websocket server. * * List of values are such like below: * * - `NONE`: The `{@link WebSocketServer} instance is newly created, but did nothing yet. * - `OPENING`: The {@link WebSocketServer.open} method is on running. * - `OPEN`: The websocket server is online. * - `CLOSING`: The {@link WebSocketServer.close} method is on running. * - `CLOSED`: The websocket server is offline. */ get: function () { return this.state_; }, enumerable: false, configurable: true }); return WebSocketServer; }()); exports.WebSocketServer = WebSocketServer; /** * */ (function (WebSocketServer) { })(WebSocketServer || (exports.WebSocketServer = WebSocketServer = {})); //# sourceMappingURL=WebSocketServer.js.map