UNPKG

@soketi/soketi

Version:

Just another simple, fast, and resilient open-source WebSockets server.

197 lines (196 loc) 9.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Cli = void 0; const fs_1 = require("fs"); const __1 = require(".."); const server_1 = require("./../server"); class Cli { constructor(pm2 = false) { this.pm2 = pm2; this.envVariables = { ADAPTER_DRIVER: 'adapter.driver', ADAPTER_CLUSTER_REQUESTS_TIMEOUT: 'adapter.cluster.requestsTimeout', ADAPTER_REDIS_PREFIX: 'adapter.redis.prefix', ADAPTER_REDIS_CLUSTER_MODE: 'adapter.redis.clusterMode', ADAPTER_REDIS_REQUESTS_TIMEOUT: 'adapter.redis.requestsTimeout', ADAPTER_REDIS_SUB_OPTIONS: 'adapter.redis.redisSubOptions', ADAPTER_REDIS_PUB_OPTIONS: 'adapter.redis.redisPubOptions', ADAPTER_NATS_PREFIX: 'adapter.nats.prefix', ADAPTER_NATS_SERVERS: 'adapter.nats.servers', ADAPTER_NATS_USER: 'adapter.nats.user', ADAPTER_NATS_PASSWORD: 'adapter.nats.pass', ADAPTER_NATS_TOKEN: 'adapter.nats.token', ADAPTER_NATS_TIMEOUT: 'adapter.nats.timeout', ADAPTER_NATS_REQUESTS_TIMEOUT: 'adapter.nats.requestsTimeout', ADAPTER_NATS_NODES_NUMBER: 'adapter.nats.nodesNumber', APP_MANAGER_DRIVER: 'appManager.driver', APP_MANAGER_CACHE_ENABLED: 'appManager.cache.enabled', APP_MANAGER_CACHE_TTL: 'appManager.cache.ttl', APP_MANAGER_DYNAMODB_TABLE: 'appManager.dynamodb.table', APP_MANAGER_DYNAMODB_REGION: 'appManager.dynamodb.region', APP_MANAGER_DYNAMODB_ENDPOINT: 'appManager.dynamodb.endpoint', APP_MANAGER_MYSQL_TABLE: 'appManager.mysql.table', APP_MANAGER_MYSQL_VERSION: 'appManager.mysql.version', APP_MANAGER_POSTGRES_TABLE: 'appManager.postgres.table', APP_MANAGER_POSTGRES_VERSION: 'appManager.postgres.version', APP_MANAGER_MYSQL_USE_V2: 'appManager.mysql.useMysql2', CHANNEL_LIMITS_MAX_NAME_LENGTH: 'channelLimits.maxNameLength', CHANNEL_CACHE_TTL: 'channelLimits.cacheTtl', CACHE_DRIVER: 'cache.driver', CACHE_REDIS_CLUSTER_MODE: 'cache.redis.clusterMode', CACHE_REDIS_OPTIONS: 'cache.redis.redisOptions', CLUSTER_CHECK_INTERVAL: 'cluster.checkInterval', CLUSTER_HOST: 'cluster.hostname', CLUSTER_IGNORE_PROCESS: 'cluster.ignoreProcess', CLUSTER_BROADCAST_ADDRESS: 'cluster.broadcast', CLUSTER_KEEPALIVE_INTERVAL: 'cluster.helloInterval', CLUSTER_MASTER_TIMEOUT: 'cluster.masterTimeout', CLUSTER_MULTICAST_ADDRESS: 'cluster.multicast', CLUSTER_NODE_TIMEOUT: 'cluster.nodeTimeout', CLUSTER_PORT: 'cluster.port', CLUSTER_PREFIX: 'cluster.prefix', CLUSTER_UNICAST_ADDRESSES: 'cluster.unicast', DEBUG: 'debug', DEFAULT_APP_ID: 'appManager.array.apps.0.id', DEFAULT_APP_KEY: 'appManager.array.apps.0.key', DEFAULT_APP_SECRET: 'appManager.array.apps.0.secret', DEFAULT_APP_MAX_CONNS: 'appManager.array.apps.0.maxConnections', DEFAULT_APP_ENABLE_CLIENT_MESSAGES: 'appManager.array.apps.0.enableClientMessages', DEFAULT_APP_ENABLED: 'appManager.array.apps.0.enabled', DEFAULT_APP_MAX_BACKEND_EVENTS_PER_SEC: 'appManager.array.apps.0.maxBackendEventsPerSecond', DEFAULT_APP_MAX_CLIENT_EVENTS_PER_SEC: 'appManager.array.apps.0.maxClientEventsPerSecond', DEFAULT_APP_MAX_READ_REQ_PER_SEC: 'appManager.array.apps.0.maxReadRequestsPerSecond', DEFAULT_APP_USER_AUTHENTICATION: 'appManager.array.apps.0.enableUserAuthentication', DEFAULT_APP_WEBHOOKS: 'appManager.array.apps.0.webhooks', DB_POOLING_ENABLED: 'databasePooling.enabled', DB_POOLING_MIN: 'databasePooling.min', DB_POOLING_MAX: 'databasePooling.max', DB_MYSQL_HOST: 'database.mysql.host', DB_MYSQL_PORT: 'database.mysql.port', DB_MYSQL_USERNAME: 'database.mysql.user', DB_MYSQL_PASSWORD: 'database.mysql.password', DB_MYSQL_DATABASE: 'database.mysql.database', DB_POSTGRES_HOST: 'database.postgres.host', DB_POSTGRES_PORT: 'database.postgres.port', DB_POSTGRES_USERNAME: 'database.postgres.user', DB_POSTGRES_PASSWORD: 'database.postgres.password', DB_POSTGRES_DATABASE: 'database.postgres.database', DB_REDIS_HOST: 'database.redis.host', DB_REDIS_PORT: 'database.redis.port', DB_REDIS_DB: 'database.redis.db', DB_REDIS_USERNAME: 'database.redis.username', DB_REDIS_PASSWORD: 'database.redis.password', DB_REDIS_KEY_PREFIX: 'database.redis.keyPrefix', DB_REDIS_SENTINELS: 'database.redis.sentinels', DB_REDIS_SENTINEL_PASSWORD: 'database.redis.sentinelPassword', DB_REDIS_CLUSTER_NODES: 'database.redis.clusterNodes', DB_REDIS_INSTANCE_NAME: 'database.redis.name', EVENT_MAX_BATCH_SIZE: 'eventLimits.maxBatchSize', EVENT_MAX_CHANNELS_AT_ONCE: 'eventLimits.maxChannelsAtOnce', EVENT_MAX_NAME_LENGTH: 'eventLimits.maxNameLength', EVENT_MAX_SIZE_IN_KB: 'eventLimits.maxPayloadInKb', HOST: 'host', HTTP_ACCEPT_TRAFFIC_MEMORY_THRESHOLD: 'httpApi.acceptTraffic.memoryThreshold', METRICS_ENABLED: 'metrics.enabled', METRICS_DRIVER: 'metrics.driver', METRICS_HOST: 'metrics.host', METRICS_PROMETHEUS_PREFIX: 'metrics.prometheus.prefix', METRICS_SERVER_PORT: 'metrics.port', MODE: 'mode', PORT: 'port', PATH_PREFIX: 'pathPrefix', PRESENCE_MAX_MEMBER_SIZE: 'presence.maxMemberSizeInKb', PRESENCE_MAX_MEMBERS: 'presence.maxMembersPerChannel', QUEUE_DRIVER: 'queue.driver', QUEUE_REDIS_CONCURRENCY: 'queue.redis.concurrency', QUEUE_REDIS_OPTIONS: 'queue.redis.redisOptions', QUEUE_REDIS_CLUSTER_MODE: 'queue.redis.clusterMode', QUEUE_SQS_REGION: 'queue.sqs.region', QUEUE_SQS_CLIENT_OPTIONS: 'queue.sqs.clientOptions', QUEUE_SQS_URL: 'queue.sqs.queueUrl', QUEUE_SQS_ENDPOINT: 'queue.sqs.endpoint', QUEUE_SQS_PROCESS_BATCH: 'queue.sqs.processBatch', QUEUE_SQS_BATCH_SIZE: 'queue.sqs.batchSize', QUEUE_SQS_POLLING_WAIT_TIME_MS: 'queue.sqs.pollingWaitTimeMs', RATE_LIMITER_DRIVER: 'rateLimiter.driver', RATE_LIMITER_REDIS_OPTIONS: 'rateLimiter.redis.redisOptions', RATE_LIMITER_REDIS_CLUSTER_MODE: 'rateLimiter.redis.clusterMode', SHUTDOWN_GRACE_PERIOD: 'shutdownGracePeriod', SSL_CERT: 'ssl.certPath', SSL_KEY: 'ssl.keyPath', SSL_PASS: 'ssl.passphrase', SSL_CA: 'ssl.caPath', USER_AUTHENTICATION_TIMEOUT: 'userAuthenticationTimeout', WEBHOOKS_BATCHING: 'webhooks.batching.enabled', WEBHOOKS_BATCHING_DURATION: 'webhooks.batching.duration', }; this.server = new server_1.Server; this.server.pm2 = pm2; } overwriteOptionsFromEnv() { require('dotenv').config(); for (let envVar in this.envVariables) { let value = process.env[`SOKETI_${envVar}`] || null; let optionKey = this.envVariables[envVar.replace('SOKETI_', '')]; if (value !== null) { let json = null; if (typeof value === 'string') { try { json = JSON.parse(value); } catch (e) { json = null; } if (json !== null) { value = json; } } let settingObject = {}; settingObject[optionKey] = value; this.server.setOptions(settingObject); } } } overwriteOptionsFromConfig(path) { if (!path) { return; } try { let config = JSON.parse((0, fs_1.readFileSync)(path, { encoding: 'utf-8' })); for (let optionKey in config) { let value = config[optionKey]; let settingObject = {}; settingObject[optionKey] = value; this.server.setOptions(settingObject); } } catch (e) { __1.Log.errorTitle('There was an error while parsing the JSON in your config file. It has not been loaded.'); } } static async start(cliArgs) { return (new Cli).start(cliArgs); } static async startWithPm2(cliArgs) { return (new Cli(true)).start(cliArgs); } async start(cliArgs) { this.overwriteOptionsFromConfig(cliArgs ? cliArgs.config : null); this.overwriteOptionsFromEnv(); const handleFailure = () => { this.server.stop().then(() => { process.exit(); }); }; process.on('SIGINT', handleFailure); process.on('SIGHUP', handleFailure); process.on('SIGTERM', handleFailure); process.on('uncaughtException', (err, origin) => { __1.Log.error('process uncaughtException'); __1.Log.error({ err, origin }); handleFailure(); }); return this.server.start(); } } exports.Cli = Cli;