Servers are used to represent implementations for inbound transports and/or protocols such as REST over http, etc. They typically listen for requests on a specific port, handle them, and return appropriate responses. A single application can have multiple server instances listening on different ports and working with different protocols.
Creating a server involves working with the kernel, dispatching events, processing the request, building the response, error handling, etc.
Fortunately @rxstack has created two ready-to-use server modules for you
express-server module and
socketio-server module
Here is how you can import them in your application:
import {Application} from '@rxstack/core'
import {ExpressModule} from '@rxstack/express-server';
import {SocketioModule} from '@rxstack/socketio-server';
// creates application instance and starts the servers
new Application({
// ...
imports: [
ExpressModule.configure({'port': 3000}),
SocketioModule.configure({'port': 4000})
],
// enabling servers
servers: [ExpressModule.serverName, SocketioModule.serverName],
}).start();Servers should dispatch some specific events during bootstrap, client connect and disconnect.
The server.configure event is used to configure the server before it is started.
Purpose: registering native middlewares, set specific server configurations and etc.
Let's create the listener:
import {Injectable} from 'injection-js';
import {Observe} from '@rxstack/async-event-dispatcher';
import {ServerConfigurationEvent, ServerEvents} from '@rxstack/core';
import {ExpressServer} from '@rxstack/express-server';
import {Application} from 'express';
const cors = require('cors');
@Injectable()
export class ExpressServerConfigurationListener {
@Observe(ServerEvents.CONFIGURE)
async onConfigure(event: ServerConfigurationEvent): Promise<void> {
if (event.server.getName() === ExpressServer.serverName) {
const app: Application = event.server.getEngine();
app
.options('*', cors())
.use(cors())
;
}
}
}Make sure that listener is registered in the application providers.
The server.connected event is dispatched when client is connected to the server. It is available only in socket servers.
import {Injectable} from 'injection-js';
import {Observe} from '@rxstack/async-event-dispatcher';
import {ConnectionEvent, ServerEvents} from '@rxstack/core';
@Injectable()
export class SocketServerListener {
@Observe(ServerEvents.CONNECTED)
async onConnect(event: ConnectionEvent): Promise<void> {
// do something
}
}The server.disconnected event is dispatched when client is disconnected from the server. It is available only in socket servers.
Purpose: it is very useful with
@rxstack-channels
import {Injectable} from 'injection-js';
import {Observe} from '@rxstack/async-event-dispatcher';
import {ConnectionEvent, ServerEvents} from '@rxstack/core';
@Injectable()
export class SocketServerListener {
@Observe(ServerEvents.DISCONNECTED)
async onDisconnect(event: ConnectionEvent): Promise<void> {
// do something
}
}Creating a server module is relatively simple. You need to extend
AbstractServer class
and implement certain methods. It needs also to be registered in the application providers:
import {SERVER_REGISTRY} from '@rxstack/core';
// ...
providers: [
{ provide: SERVER_REGISTRY, useClass: MyServer, multi: true },
],
servers: ['my-server']The best tutorial is to study how build-in server modules are created: