@soketi/soketi
Version:
Just another simple, fast, and resilient open-source WebSockets server.
197 lines (196 loc) • 9.67 kB
JavaScript
;
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;