Cleaned up HttpServer. WebSocket connects
This commit is contained in:
@@ -3,22 +3,44 @@ import {LoggerFactory} from '@techniker-me/logger';
|
|||||||
import HttpServer from './net/http/HttpServer';
|
import HttpServer from './net/http/HttpServer';
|
||||||
import HealthCheckRoute from './health/HealthCheckRoute';
|
import HealthCheckRoute from './health/HealthCheckRoute';
|
||||||
import HealthCheck from './health/HealthCheck';
|
import HealthCheck from './health/HealthCheck';
|
||||||
|
import WebSocketServer from './net/websocket/WebSocketServer';
|
||||||
|
|
||||||
const logger = LoggerFactory.getLogger('Server');
|
const logger = LoggerFactory.getLogger('Server');
|
||||||
const healthCheck = new HealthCheck();
|
const healthCheck = new HealthCheck();
|
||||||
const healthCheckRoute = new HealthCheckRoute(healthCheck);
|
const healthCheckRoute = new HealthCheckRoute(healthCheck);
|
||||||
|
|
||||||
const httpServer = new HttpServer('http', 3000, healthCheckRoute, {}, '', [], path.resolve(process.cwd(), 'assets', 'favicon', 'favicon.ico'), {});
|
const httpServer = new HttpServer('http', 3000, healthCheckRoute, {}, '', [], path.resolve(process.cwd(), 'assets', 'favicon', 'favicon.ico'), {});
|
||||||
|
httpServer.on('error', () => logger.error('[HttpServer] Error'));
|
||||||
|
|
||||||
httpServer.on('error', () => {
|
function connectDelegate(connection: ExtendedWebSocket, req: IncomingMessage) {
|
||||||
console.log('[HttpServer] Error event');
|
console.log('[Server] Connect delegate');
|
||||||
logger.error('[HttpServer] Error');
|
}
|
||||||
});
|
|
||||||
httpServer.on('request', (method: string, url: string, statusCode: number, headers: Record<string, string>) => {
|
function requestDelegate(connection: ExtendedWebSocket, message: Buffer) {
|
||||||
console.log(`[HttpServer] Request: ${method} ${url} -> ${statusCode}`);
|
console.log('[Server] Request delegate');
|
||||||
});
|
}
|
||||||
|
|
||||||
|
function disconnectDelegate(connection: ExtendedWebSocket, reasonCode: number, description: string) {
|
||||||
|
console.log('[Server] Disconnect delegate');
|
||||||
|
}
|
||||||
|
|
||||||
|
function pongDelegate(connection: ExtendedWebSocket, message: Buffer) {
|
||||||
|
console.log('[Server] Pong delegate');
|
||||||
|
}
|
||||||
|
|
||||||
httpServer
|
httpServer
|
||||||
.start()
|
.start()
|
||||||
.then(() => console.log('[Server] Server started successfully'))
|
.then(() => {
|
||||||
.catch(err => console.log('[Server] Server failed to start:', err));
|
const server = httpServer.getServer();
|
||||||
|
|
||||||
|
|
||||||
|
if (server) {
|
||||||
|
const websocketServer = new WebSocketServer(server, {path: '/ws'});
|
||||||
|
|
||||||
|
websocketServer.start(connectDelegate, requestDelegate, disconnectDelegate, pongDelegate);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.error('[Server] Failed to get HTTP server instance');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => console.log('[Server] Server failed to start:', err));
|
||||||
|
|||||||
@@ -155,6 +155,11 @@ export default class HttpServer {
|
|||||||
this._eventEmitter.on(event, handler);
|
this._eventEmitter.on(event, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public getServer(): Nullable<Server> {
|
||||||
|
return this._server.value;
|
||||||
|
}
|
||||||
|
|
||||||
private configureListener() {
|
private configureListener() {
|
||||||
if (!this._app.value) {
|
if (!this._app.value) {
|
||||||
throw new Error('Unable to configure listener, no app instance found');
|
throw new Error('Unable to configure listener, no app instance found');
|
||||||
@@ -344,13 +349,16 @@ export default class HttpServer {
|
|||||||
|
|
||||||
let catchAllHandler: Nullable<RequestHandler> = null;
|
let catchAllHandler: Nullable<RequestHandler> = null;
|
||||||
|
|
||||||
const registerRoutes = (routes: Record<string, RequestHandler>): void => {
|
const registerRoutes = (method: string, routes: Record<string, RequestHandler>): void => {
|
||||||
for (const route of Object.entries(routes)) {
|
for (const route of Object.entries(routes)) {
|
||||||
|
|
||||||
|
if (!route) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const [name, handler] = route;
|
const [name, handler] = route;
|
||||||
|
|
||||||
console.log(`[${name}] registering [%o]`, handler);
|
|
||||||
if (name === '*') {
|
if (name === '*') {
|
||||||
console.log('Catch-all handler', name, handler);
|
|
||||||
if (catchAllHandler) {
|
if (catchAllHandler) {
|
||||||
throw new Error(`Only one catch-all handler can ber registered per server, ignoring conflicting catch-all`);
|
throw new Error(`Only one catch-all handler can ber registered per server, ignoring conflicting catch-all`);
|
||||||
}
|
}
|
||||||
@@ -359,21 +367,15 @@ export default class HttpServer {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._logger.debug(`Registering [GET] route [${name}] with [%o]`, handler);
|
this._logger.debug(`Registering [${method}] route [${name}] handler`);
|
||||||
app.get(name, handler);
|
app[method.toLowerCase() as 'get' | 'post' | 'put' | 'patch' | 'delete'](name, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRoutes = this._routes.getGETRoutes();
|
registerRoutes('GET', this._routes.getGETRoutes());
|
||||||
const postRoutes = this._routes.getPOSTRoutes();
|
registerRoutes('POST', this._routes.getPOSTRoutes());
|
||||||
const putRoutes = this._routes.getPUTRoutes();
|
registerRoutes('PUT', this._routes.getPUTRoutes());
|
||||||
const patchRoutes = this._routes.getPATCHRoutes();
|
registerRoutes('PATCH', this._routes.getPATCHRoutes());
|
||||||
const deleteRoutes = this._routes.getDELETERoutes();
|
registerRoutes('DELETE', this._routes.getDELETERoutes());
|
||||||
|
|
||||||
registerRoutes(getRoutes);
|
|
||||||
registerRoutes(postRoutes);
|
|
||||||
registerRoutes(putRoutes);
|
|
||||||
registerRoutes(patchRoutes);
|
|
||||||
registerRoutes(deleteRoutes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import ws, {WebSocketServer as WSServer, WebSocket} from 'ws';
|
|||||||
import Assert from '../../lang/Assert';
|
import Assert from '../../lang/Assert';
|
||||||
import Strings from '../../lang/Strings';
|
import Strings from '../../lang/Strings';
|
||||||
import WebsocketExtensions from 'websocket-extensions';
|
import WebsocketExtensions from 'websocket-extensions';
|
||||||
import deflate from 'permessage-deflate';
|
|
||||||
|
|
||||||
interface ExtendedWebSocket extends WebSocket {
|
interface ExtendedWebSocket extends WebSocket {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -100,11 +99,12 @@ export default class WebSocketServer {
|
|||||||
this._server = new WSServer(serverOptions);
|
this._server = new WSServer(serverOptions);
|
||||||
this._extensions = new WebsocketExtensions();
|
this._extensions = new WebsocketExtensions();
|
||||||
|
|
||||||
this._extensions.add(deflate());
|
// this._extensions.add(deflate());
|
||||||
(this._server as WSServer & {_server?: HttpServer})._server = this._httpServer;
|
(this._server as WSServer & {_server?: HttpServer})._server = this._httpServer;
|
||||||
this._httpServer.on('error', this._server.emit.bind(this._server, 'error'));
|
this._httpServer.on('error', this._server.emit.bind(this._server, 'error'));
|
||||||
this._httpServer.on('listening', this._server.emit.bind(this._server, 'listening'));
|
this._httpServer.on('listening', this._server.emit.bind(this._server, 'listening'));
|
||||||
this._httpServer.on('upgrade', (req, socket, head) => {
|
this._httpServer.on('upgrade', (req, socket, head) => {
|
||||||
|
this._logger.debug(`[HttpServer] Upgrade to WebSocket: ${req.method} ${req.url}`);
|
||||||
if (!req.url?.startsWith(path)) {
|
if (!req.url?.startsWith(path)) {
|
||||||
this._logger.debug(`Skipping upgrade of http request due to incorrect path [${req.url}]`);
|
this._logger.debug(`Skipping upgrade of http request due to incorrect path [${req.url}]`);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user