diff --git a/website/pages/docs/examples/nestjs-websocket.mdx b/website/pages/docs/examples/nestjs-websocket.mdx index b3a0910..c5db5cd 100644 --- a/website/pages/docs/examples/nestjs-websocket.mdx +++ b/website/pages/docs/examples/nestjs-websocket.mdx @@ -95,7 +95,9 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -113,7 +115,9 @@ export class CalculateController { const header: ICalcConfig = acceptor.header; const listener: Driver = acceptor.getDriver(); const provider: SimpleCalculator = new SimpleCalculator(header, listener); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -134,7 +138,9 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -155,7 +161,9 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } } ``` @@ -306,6 +314,14 @@ When defining WebSocket operation, attach `@WebSocketRoute()` decorator to the t With such controller patterned WebSocket operation, you can manage WebSocket API endpoints much effectively and easily. Also, you can generate SDK (Software Development Kit) library for your client application through `Nestia`. Let's see how to generate SDK library, and how it would be looked like in the next section. + +**Ping** + +If client comes from web browser, the connection would be closed automatically after a certain period of time if there's no signal. In the Google Chrome case, it automatically closes the connection after 60 seconds. + +To make the connection alive forcibly, you can ping a signal to the remote client repeatedly in the specified interval by calling the [`WebSocketAcceptor.ping()`](/api/classes/WebSocketAcceptor-1.html#ping) method. Therefore, when developing WebSocket server application, consider to calling the [`WebSocketAcceptor.ping()`](/api/classes/WebSocketAcceptor-1.html#ping) method after [accepting](/api/classes/WebSocketAcceptor-1.html#accept) the connection. + + ### Software Development Kit diff --git a/website/pages/docs/examples/object-oriented-network.mdx b/website/pages/docs/examples/object-oriented-network.mdx index 2be48ac..4f8d582 100644 --- a/website/pages/docs/examples/object-oriented-network.mdx +++ b/website/pages/docs/examples/object-oriented-network.mdx @@ -416,7 +416,9 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -434,7 +436,9 @@ export class CalculateController { const header: ICalcConfig = acceptor.header; const listener: Driver = acceptor.getDriver(); const provider: SimpleCalculator = new SimpleCalculator(header, listener); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -455,7 +459,9 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -476,7 +482,9 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } } ``` diff --git a/website/pages/docs/examples/remote-function-call.mdx b/website/pages/docs/examples/remote-function-call.mdx index 8944713..2764676 100644 --- a/website/pages/docs/examples/remote-function-call.mdx +++ b/website/pages/docs/examples/remote-function-call.mdx @@ -23,7 +23,7 @@ npm start ## Client Program -```typescript filename="examples/remote-function-call/src/client.ts" showLineNumbers {13-19} +```typescript filename="examples/remote-function-call/src/client.ts" showLineNumbers {11-17} import { Driver, WebSocketConnector } from "tgrid"; export const webSocketClientMain = async () => { @@ -81,7 +81,8 @@ export const webSocketServerMain = async () => { > = new WebSocketServer(); await server.open(37_000, async (acceptor) => { const provider: Calculator = new Calculator(); - await acceptor.accept(provider); + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION }); return server; }; diff --git a/website/pages/docs/examples/remote-object-call.mdx b/website/pages/docs/examples/remote-object-call.mdx index bdf044c..4124a49 100644 --- a/website/pages/docs/examples/remote-object-call.mdx +++ b/website/pages/docs/examples/remote-object-call.mdx @@ -140,7 +140,10 @@ export const webSocketServerMain = async () => { await server.open(37_000, async (acceptor) => { const config: ICalcConfig = acceptor.header; const listener: Driver = acceptor.getDriver(); - await acceptor.accept(new CompositeCalculator(config, listener)); + const provider: CompositeCalculator = new CompositeCalculator(config, listener); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION }); return server; }; diff --git a/website/pages/docs/features/components.mdx b/website/pages/docs/features/components.mdx index e2cbb06..7c83368 100644 --- a/website/pages/docs/features/components.mdx +++ b/website/pages/docs/features/components.mdx @@ -109,7 +109,13 @@ export const webSocketServerMain = async () => { await acceptor.accept(new StatisticsCalculator(config, listener)); else if (acceptor.path === "/scientific") await acceptor.accept(new ScientificCalculator(config, listener)); - else await acceptor.reject(1002, `WebSocket API endpoint not found.`); + else { + await acceptor.reject(1002, `WebSocket API endpoint not found.`); + return; + } + + // PING REPEATEDLY TO KEEP CONNECTION + acceptor.ping(15_000); }); return server; }; @@ -193,7 +199,13 @@ export const webSocketServerMain = async () => { await acceptor.accept(new StatisticsCalculator(config, listener)); else if (acceptor.path === "/scientific") await acceptor.accept(new ScientificCalculator(config, listener)); - else await acceptor.reject(1002, `WebSocket API endpoint not found.`); + else { + await acceptor.reject(1002, `WebSocket API endpoint not found.`); + return; + } + + // PING REPEATEDLY TO KEEP CONNECTION + acceptor.ping(15_000); }); return server; }; diff --git a/website/pages/docs/features/websocket.mdx b/website/pages/docs/features/websocket.mdx index 26723b4..6cc6beb 100644 --- a/website/pages/docs/features/websocket.mdx +++ b/website/pages/docs/features/websocket.mdx @@ -51,7 +51,13 @@ export const webSocketServerMain = async () => { await acceptor.accept(new StatisticsCalculator(config, listener)); else if (acceptor.path === "/scientific") await acceptor.accept(new ScientificCalculator(config, listener)); - else await acceptor.reject(1002, `WebSocket API endpoint not found.`); + else { + await acceptor.reject(1002, `WebSocket API endpoint not found.`); + return; + } + + // PING REPEATEDLY TO KEEP CONNECTION + acceptor.ping(15_000); }); return server; }; @@ -252,7 +258,13 @@ export const webSocketServerMain = async () => { await acceptor.accept(new StatisticsCalculator(config, listener)); else if (acceptor.path === "/scientific") await acceptor.accept(new ScientificCalculator(config, listener)); - else await acceptor.reject(1002, `WebSocket API endpoint not found.`); + else { + await acceptor.reject(1002, `WebSocket API endpoint not found.`); + return; + } + + // PING REPEATEDLY TO KEEP CONNECTION + acceptor.ping(15_000); }, ); return server; @@ -395,7 +407,15 @@ The `WebSocketAcceptor` is a [communicator](./components/#communicator) class in When the closure function being called by the connection of a remote client, you can determine whether to accept the client's connection or not, reading the [`WebSocketAcceptor.header`](/api/classes/WebSocketAcceptor-1.html#header-1) or [`WebSocketAcceptor.path`](/api/classes/WebSocketAcceptor-1.html#path-1) properties. If you've decided to accept the connection, call the [`WebSocketAcceptor.accept()`](/api/classes/WebSocketAcceptor-1.html#accept) method with `Provider` instance. Otherwise, reject it through the [`WebSocketAcceptor.reject()`](/api/classes/WebSocketAcceptor-1.html#reject) method. -After [accepting](/api/classes/WebSocketAcceptor-1.html#accept) the connection, don't forget to [`closing`](/api/classes/WebSocketAcceptor-1.html#close) the connection after your business logic has been completed to clean up the resources. Otherwise the closing must be performed by the remote client, you can wait the remote client's closing signal by the [`WebSocketAcceptor.join()`](/api/classes/WebSocketAcceptor-1.html#join) method. +Also, don't forget to [`closing`](/api/classes/WebSocketAcceptor-1.html#close) the connection after your business logic has been completed to clean up the resources. Otherwise the closing must be performed by the remote client, you can wait the remote client's closing signal by the [`WebSocketAcceptor.join()`](/api/classes/WebSocketAcceptor-1.html#join) method. + + +**Ping** + +If client comes from web browser, the connection would be closed automatically after a certain period of time if there's no signal. In the Google Chrome case, it automatically closes the connection after 60 seconds. + +To make the connection alive forcibly, you can ping a signal to the remote client repeatedly in the specified interval by calling the [`WebSocketAcceptor.ping()`](/api/classes/WebSocketAcceptor-1.html#ping) method. Therefore, when developing WebSocket server application, consider to calling the [`WebSocketAcceptor.ping()`](/api/classes/WebSocketAcceptor-1.html#ping) method after [accepting](/api/classes/WebSocketAcceptor-1.html#accept) the connection. + ### `WebSocketConnector` @@ -604,7 +624,8 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -622,7 +643,9 @@ export class CalculateController { const header: ICalcConfig = acceptor.header; const listener: Driver = acceptor.getDriver(); const provider: SimpleCalculator = new SimpleCalculator(header, listener); - await acceptor.accept(provider); + + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -643,7 +666,8 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } /** @@ -664,7 +688,8 @@ export class CalculateController { header, listener ); - await acceptor.accept(provider); + await acceptor.accept(provider); // ACCEPT CONNECTION + acceptor.ping(15_000); // PING REPEATEDLY TO KEEP CONNECTION } } ``` diff --git a/website/pages/docs/remote-procedure-call.mdx b/website/pages/docs/remote-procedure-call.mdx index f9be19a..f4c9fd9 100644 --- a/website/pages/docs/remote-procedure-call.mdx +++ b/website/pages/docs/remote-procedure-call.mdx @@ -84,7 +84,13 @@ export const webSocketServerMain = async () => { await acceptor.accept(new StatisticsCalculator(config, listener)); else if (acceptor.path === "/scientific") await acceptor.accept(new ScientificCalculator(config, listener)); - else await acceptor.reject(1002, `WebSocket API endpoint not found.`); + else { + await acceptor.reject(1002, `WebSocket API endpoint not found.`); + return; + } + + // PING REPEATEDLY TO KEEP CONNECTION + acceptor.ping(15_000); }); return server; }; @@ -361,7 +367,13 @@ export const webSocketServerMain = async () => { await acceptor.accept(new StatisticsCalculator(config, listener)); else if (acceptor.path === "/scientific") await acceptor.accept(new ScientificCalculator(config, listener)); - else await acceptor.reject(1002, `WebSocket API endpoint not found.`); + else { + await acceptor.reject(1002, `WebSocket API endpoint not found.`); + return; + } + + // PING REPEATEDLY TO KEEP CONNECTION + acceptor.ping(15_000); }); return server; };