Skip to content

Commit

Permalink
feat : add websocket servers
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamensuli committed Feb 4, 2024
1 parent 3380890 commit 97a34e4
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 68 deletions.
4 changes: 2 additions & 2 deletions src/nodefony/src/types/nodefony.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export * from "../command/Command";
export * from "../command/Builder";
export * from "../Cli";
export * from "../Nodefony";
export * from "../Kernel/Kernel";
export * from "../Kernel/Module";
export * from "../kernel/Kernel";
export * from "../kernel/Module";

//export * from "../index";
2 changes: 2 additions & 0 deletions src/packages/@nodefony/http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import HttpKernel from "./nodefony/service/http-kernel";
import HttpServer from "./nodefony/service/servers/server-http";
import HttpsServer from "./nodefony/service/servers/server-https";
import WebsocketServer from "./nodefony/service/servers/server-websocket";
import WebsocketSecureServer from "./nodefony/service/servers/server-websocket-secure";
import StaticServer from "./nodefony/service/servers/server-static";
import networkCommand from "./nodefony/command/networkCommand";
import { fileURLToPath } from "url";
Expand All @@ -26,6 +27,7 @@ class Http extends Module {
this.addService(HttpsServer, this.httpKernel);
this.addService(StaticServer, this.httpKernel);
this.addService(WebsocketServer, this.httpKernel);
this.addService(WebsocketSecureServer, this.httpKernel);
return this;
}

Expand Down
14 changes: 14 additions & 0 deletions src/packages/@nodefony/http/nodefony/service/http-kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import https from "node:http";
import http2 from "node:http2";
import httpServer from "../service/servers/server-http";
import httpsServer from "../service/servers/server-https";
import websocketServer from "../service/servers/server-websocket";
import websocketSecureServer from "../service/servers/server-websocket-secure";
import Statics from "./servers/server-static";
import WebsocketContext from "../src/context/websocket/WebsocketContext";
import HttpContext from "../src/context/http/HttpContext";
Expand Down Expand Up @@ -206,6 +208,18 @@ class HttpKernel extends Service {
await serverHttps.createServer();
servers.push(serverHttps);
}
const serverWebsocket: websocketServer = this.get("server-websocket");
if (serverWebsocket && serverHttp) {
await serverWebsocket.createServer(serverHttp);
servers.push(serverWebsocket);
}
const serverWebsocketSecure: websocketSecureServer = this.get(
"server-websocket-secure"
);
if (serverWebsocketSecure && serverHttps) {
await serverWebsocketSecure.createServer(serverHttps);
servers.push(serverWebsocketSecure);
}
return servers;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// https://github.com/Worlize/WebSocket-Node/wiki/Documentation

import websocket from "websocket";
import nodefony, {
extend,
Service,
Kernel,
Container,
Event,
Module,
FamilyType,
DefaultOptionsService,
} from "nodefony";
import HttpKernel, { ProtocolType, ServerType } from "../http-kernel";
import { AddressInfo } from "node:net";
import https from "node:https";
import httpsServers from "./server-https";

class Websocket extends Service {
module: Module;
httpKernel: HttpKernel;
ready: boolean = false;
server: websocket.server | null = null;
port: number;
domain: string;
protocol: ProtocolType = "1.1";
family: FamilyType | null = null;
scheme: string = "wss";
address: string | null = null;
type: ServerType = "websocket-secure";
infos: AddressInfo | null = null;
constructor(module: Module, httpKernel: HttpKernel) {
super(
"server-websocket-secure",
module.container as Container,
module.notificationsCenter as Event,
module.options.websocket
);
this.module = module;
this.httpKernel = httpKernel;
this.port = this.setPort();
this.domain = this.kernel?.domain as string;
this.ready = false;
}

setPort(): number {
if (this.kernel?.options.servers?.https) {
return this.kernel?.options.servers?.https?.port || 0;
}
return 0;
}

async createServer(serverHttps: httpsServers): Promise<websocket.server> {
return new Promise((resolve, reject) => {
try {
this.infos = (
serverHttps.server as https.Server
).address() as AddressInfo;
if (this.infos) {
this.port = this.infos.port;
this.address = this.infos.address;
this.family = this.infos.family as FamilyType;
this.protocol = serverHttps.protocol;
}
const conf: websocket.IServerConfig = extend(true, {}, this.options);
conf.httpServer = serverHttps.server as https.Server;
this.server = new websocket.server(conf);
this.server.on("request", (request) =>
this.httpKernel.onWebsocketRequest(request, this.type)
);
this.kernel?.prependOnceListener(
"onTerminate",
() =>
new Promise((resolve, reject) => {
if (this.server && this.ready) {
this.server.broadcast(
JSON.stringify({
nodefony: {
state: "shutDown",
},
})
);
setTimeout(() => {
try {
if (this.server?.config?.httpServer) {
this.server.shutDown();
}
this.log(
` SHUTDOWN WEBSOCKET Server is listening on DOMAIN : ${this.domain} PORT : ${this.port}`,
"INFO"
);
return resolve(true);
} catch (e) {
return reject(e);
}
}, 500);
return;
}
return resolve(true);
})
);
if (this.server) {
this.ready = true;
}
this.module.fire("onServersReady", this.type, this);
return resolve(this.server);
} catch (e) {
this.log(e, "ERROR");
return reject(e);
}
});
}

removePendingRequests(url: string) {
if (url && this.server) {
this.server.pendingRequests.forEach((request, index) => {
if (request.httpRequest.url === url) {
try {
request.emit("requestResolved", request);
request.emit("requestRejected", request);
this.server?.pendingRequests.splice(index, 1);
} catch (e) {}
}
});
}
}

showBanner(): void {
if (this.infos) {
this.log(
`Server Listen on ${this.scheme}://${this.infos.address}:${this.infos.port} Family: ${this.infos.family} Protocol : ${this.protocol}`
);
}
}
}

export default Websocket;
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import websocket from "websocket";
import nodefony, {
extend,
Service,
Kernel,
Container,
Expand All @@ -13,8 +14,7 @@ import nodefony, {
import HttpKernel, { ProtocolType, ServerType } from "../http-kernel";
import { AddressInfo } from "node:net";
import http from "node:http";

import http2 from "node:http2";
import httpServer from "./server-http";

class Websocket extends Service {
module: Module;
Expand All @@ -23,6 +23,7 @@ class Websocket extends Service {
server: websocket.server | null = null;
port: number;
domain: string;
protocol: ProtocolType = "1.1";
family: FamilyType | null = null;
scheme: string = "ws";
address: string | null = null;
Expand All @@ -43,75 +44,70 @@ class Websocket extends Service {
}

setPort(): number {
if (this.kernel?.options.servers?.https) {
return this.kernel?.options.servers?.https?.port || 0;
if (this.kernel?.options.servers?.http) {
return this.kernel?.options.servers?.http?.port || 0;
}
return 0;
}

createServer(http: http.Server) {
this.kernel?.once("onServersReady", (type) => {
if (type === "http") {
try {
this.infos = http.address() as AddressInfo;
if (this.infos) {
this.port = this.infos.port;
this.address = this.infos.address;
this.family = this.infos.family as FamilyType;
}
//this.settings = this.getParameters("bundles.http").websocket || {};
const conf = nodefony.extend(true, {}, this.options);
conf.httpServer = http;
this.server = new websocket.server(conf);
this.server.on("request", (request) =>
this.httpKernel.onWebsocketRequest(request, this.type)
);

this.kernel?.prependOnceListener(
"onTerminate",
() =>
new Promise((resolve, reject) => {
if (this.server && this.ready) {
this.server.broadcast(
JSON.stringify({
nodefony: {
state: "shutDown",
},
})
);
setTimeout(() => {
try {
if (this.server?.config?.httpServer) {
this.server.shutDown();
}
this.log(
` SHUTDOWN WEBSOCKET Server is listening on DOMAIN : ${this.domain} PORT : ${this.port}`,
"INFO"
);
return resolve(true);
} catch (e) {
return reject(e);
async createServer(serverHttp: httpServer): Promise<websocket.server> {
return new Promise((resolve, reject) => {
try {
this.infos = (
serverHttp.server as http.Server
).address() as AddressInfo;
if (this.infos) {
this.port = this.infos.port;
this.address = this.infos.address;
this.family = this.infos.family as FamilyType;
this.protocol = serverHttp.protocol;
}
//this.settings = this.getParameters("bundles.http").websocket || {};
const conf: websocket.IServerConfig = extend(true, {}, this.options);
conf.httpServer = serverHttp.server as http.Server;
this.server = new websocket.server(conf);
this.server.on("request", (request) =>
this.httpKernel.onWebsocketRequest(request, this.type)
);
this.kernel?.prependOnceListener(
"onTerminate",
() =>
new Promise((resolve, reject) => {
if (this.server && this.ready) {
this.server.broadcast(
JSON.stringify({
nodefony: {
state: "shutDown",
},
})
);
setTimeout(() => {
try {
if (this.server?.config?.httpServer) {
this.server.shutDown();
}
}, 500);
return;
}
return resolve(true);
})
);

if (this.server) {
this.ready = true;
}
this.module.fire("onServersReady", this.type, this);
this.log(
`Listening on DOMAIN : ws://${this.domain}:${this.port}`,
"INFO"
);
return this.server;
} catch (e) {
this.log(e, "ERROR");
throw e;
this.log(
` SHUTDOWN WEBSOCKET Server is listening on DOMAIN : ${this.domain} PORT : ${this.port}`,
"INFO"
);
return resolve(true);
} catch (e) {
return reject(e);
}
}, 500);
return;
}
return resolve(true);
})
);
if (this.server) {
this.ready = true;
}
this.module.fire("onServersReady", this.type, this);
return resolve(this.server);
} catch (e) {
this.log(e, "ERROR");
return reject(e);
}
});
}
Expand All @@ -129,6 +125,14 @@ class Websocket extends Service {
});
}
}

showBanner(): void {
if (this.infos) {
this.log(
`Server Listen on ${this.scheme}://${this.infos.address}:${this.infos.port} Family: ${this.infos.family} Protocol : ${this.protocol}`
);
}
}
}

export default Websocket;
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ import WebsocketResponse from "./websocket/Response";
import HttpResquest from "./http/Request";
import Http2Resquest from "./http2/Request";
import clc from "cli-color";
const colorLogEvent = clc.cyan.bgBlue("EVENT CONTEXT");
import http from "node:http";
import http2 from "node:http2";
import { URL } from "node:url";
import Session from "../session/session";
import Cookie from "../cookies/cookie";
const colorLogEvent = clc.cyan.bgBlue("EVENT CONTEXT");

export type contextRequest =
| HttpResquest
Expand Down

0 comments on commit 97a34e4

Please sign in to comment.