123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- ///
- /// Copyright © 2016-2023 The Thingsboard Authors
- ///
- /// Licensed under the Apache License, Version 2.0 (the "License");
- /// you may not use this file except in compliance with the License.
- /// You may obtain a copy of the License at
- ///
- /// http://www.apache.org/licenses/LICENSE-2.0
- ///
- /// Unless required by applicable law or agreed to in writing, software
- /// distributed under the License is distributed on an "AS IS" BASIS,
- /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- /// See the License for the specific language governing permissions and
- /// limitations under the License.
- ///
- import express from 'express';
- import config from 'config';
- import { _logger} from './config/logger';
- import path from 'path';
- import http, { ServerResponse } from 'http';
- import httpProxy from 'http-proxy';
- import compression from 'compression';
- import historyApiFallback from 'connect-history-api-fallback';
- import { Socket } from 'net';
- const logger = _logger('main');
- let server: http.Server | null;
- let connections: Socket[] = [];
- (async() => {
- try {
- logger.info('Starting ThingsBoard Web UI Microservice...');
- const bindAddress: string = config.get('server.address');
- const bindPort = Number(config.get('server.port'));
- const thingsboardEnableProxy: string = config.get('thingsboard.enableProxy');
- const thingsboardHost: string = config.get('thingsboard.host');
- const thingsboardPort = Number(config.get('thingsboard.port'));
- logger.info('Bind address: %s', bindAddress);
- logger.info('Bind port: %s', bindPort);
- logger.info('ThingsBoard Enable Proxy: %s', thingsboardEnableProxy);
- logger.info('ThingsBoard host: %s', thingsboardHost);
- logger.info('ThingsBoard port: %s', thingsboardPort);
- const useApiProxy = thingsboardEnableProxy === "true";
- let webDir = path.join(__dirname, 'web');
- if (typeof process.env.WEB_FOLDER !== 'undefined') {
- webDir = path.resolve(process.env.WEB_FOLDER);
- }
- logger.info('Web folder: %s', webDir);
- const app = express();
- server = http.createServer(app);
- let apiProxy: httpProxy;
- if (useApiProxy) {
- apiProxy = httpProxy.createProxyServer({
- target: {
- host: thingsboardHost,
- port: thingsboardPort
- }
- });
- apiProxy.on('error', (err, req, res) => {
- logger.warn('API proxy error: %s', err.message);
- if (res instanceof ServerResponse) {
- res.writeHead(500);
- const error = err as any;
- if (error.code && error.code === 'ECONNREFUSED') {
- res.end('Unable to connect to ThingsBoard server.');
- } else {
- res.end('ThingsBoard server connection error: ' + error.code ? error.code : '');
- }
- }
- });
- app.all('/api/*', (req, res) => {
- logger.debug(req.method + ' ' + req.originalUrl);
- apiProxy.web(req, res);
- });
- app.all('/static/rulenode/*', (req, res) => {
- apiProxy.web(req, res);
- });
- server.on('upgrade', (req, socket, head) => {
- apiProxy.ws(req, socket, head);
- });
- }
- app.use(historyApiFallback());
- app.use(compression());
- const root = path.join(webDir, 'public');
- app.use(express.static(root));
- server.listen(bindPort, bindAddress, () => {
- logger.info('==> 🌎 Listening on port %s.', bindPort);
- logger.info('Started ThingsBoard Web UI Microservice.');
- }).on('error', async (error) => {
- logger.error('Failed to start ThingsBoard Web UI Microservice: %s', error.message);
- logger.error(error.stack);
- await exit(-1);
- });
- server.on('connection', connection => {
- connections.push(connection);
- connection.on('close', () => connections = connections.filter(curr => curr !== connection));
- });
- } catch (e: any) {
- logger.error('Failed to start ThingsBoard Web UI Microservice: %s', e.message);
- logger.error(e.stack);
- await exit(-1);
- }
- })();
- [`SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
- process.once(eventType, async () => {
- logger.info(`${eventType} signal received`);
- await exit(0);
- });
- })
- process.on('exit', async (code: number) => {
- logger.info(`ThingsBoard Web UI Microservice has been stopped. Exit code: ${code}.`);
- });
- async function exit(status: number) {
- logger.info('Exiting with status: %d ...', status);
- if (server) {
- logger.info('Stopping HTTP Server...');
- connections.forEach(curr => curr.end(() => curr.destroy()));
- const _server = server;
- server = null;
- const serverClosePromise = new Promise<void>(
- (resolve, reject) => {
- _server.close((err) => {
- logger.info('HTTP Server stopped.');
- resolve();
- });
- }
- );
- await serverClosePromise;
- }
- process.exit(status);
- }
|