Skip to content

Commit

Permalink
Writing #69: docs of websocket native classes
Browse files Browse the repository at this point in the history
  • Loading branch information
samchon committed May 14, 2024
1 parent 146fc50 commit 71c8f37
Show file tree
Hide file tree
Showing 76 changed files with 1,603 additions and 651 deletions.
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,26 @@ Also, extremely easy even when composing complicated network system like grid co

```typescript
import { Driver, WebSocketConnector } from "tgrid";

import { ICalculator } from "./interfaces/ICalculator";
import { CalcEventListener } from "./providers/CalcEventListener";

export const main = async (): Promise<void> => {
const connector: WebSocketConnector<null, null, ICalculator> =
new WebSocketConnector(null, null);
// CONNECT TO WEBSOCKET SERVER
const connector: WebSocketConnector<
null, // header
CalcEventListener, // provider for remote server
ICalculator, // provider from remote server
> = new WebSocketConnector(null, new CalcEventListener());
await connector.connect("ws://127.0.0.1:443/calculator");

const remote: Driver<ICalculator> = connector.getDriver();
// RPC (YOU CAN CALL REMOTE PROCEDURES)
const calc: Driver<ICalculator> = connector.getDriver();
console.log(
await remote.plus(2, 3),
await remote.minus(7, 1),
await remote.multiplies(3, 4),
await remote.divides(9, 3),
await calc.plus(2, 3),
await calc.minus(7, 1),
await calc.multiplies(3, 4),
await calc.divides(9, 3),
);
await connector.close();
};
Expand All @@ -43,7 +50,7 @@ npm install tgrid

Just install with `npm` command. That's all.

If you're using `tgrid` with `nestia`, reference `nestia` guide documents.
If you wanna `tgrid` in `NestJS`, read `nestia` guide documents.

- [Nestia > Guide Documents > Setup](https://nestia.io/docs/setup/)
- [Nestia > Guide Documents > WebSocketRoute](https://nestia.io/docs/core/WebSocketRoute/)
Expand All @@ -68,7 +75,7 @@ Check out the document in the [website](https://tgrid.com/docs):
- [Remote Function Call](https://tgrid.com/docs/examples/remote-function-call)
- [Remote Object Call](https://tgrid.com/docs/examples/remote-object-call)
- [Object Oriented Network](https://tgrid.com/docs/examples/object-oriented-network)
- [NestJS WebSocket](https://tgrid.com/docs/examples/nestjs)
- [NestJS WebSocket SDK](https://tgrid.com/docs/examples/nestjs-websocket-sdk)
- Learn from Projects
- [Chat Application](https://tgrid.com/docs/projects/chat)
- [Grid Market](https://tgrid.com/docs/examples/market)
Expand Down
20 changes: 20 additions & 0 deletions examples/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@samchon/tgrid-example-websocket",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"websocket": "npx ts-node src/websocket/index.ts",
"websocket:server": "npx ts-node src/websocket/server.ts",
"websocket:client": "npx ts-node src/websocket/client.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"typescript": "^5.4.5"
},
"dependencies": {
"tgrid": "1.0.0-dev.20240507"
}
}
3 changes: 3 additions & 0 deletions examples/src/interfaces/ICalcConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface ICalcConfig {
precision: number;
}
5 changes: 5 additions & 0 deletions examples/src/interfaces/ICalcEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ICalcEvent {
type: string;
input: number[];
output: number;
}
5 changes: 5 additions & 0 deletions examples/src/interfaces/ICalcEventListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ICalcEvent } from "./ICalcEvent";

export interface ICalcEventListener {
on(event: ICalcEvent): void;
}
8 changes: 8 additions & 0 deletions examples/src/interfaces/ICompositeCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IScientificCalculator } from "./IScientificCalculator";
import { ISimpleCalculator } from "./ISimpleCalculator";
import { IStatisticsCalculator } from "./IStatisticsCalculator";

export interface ICompositeCalculator extends ISimpleCalculator {
scientific: IScientificCalculator;
statistics: IStatisticsCalculator;
}
5 changes: 5 additions & 0 deletions examples/src/interfaces/IScientificCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface IScientificCalculator {
pow(x: number, y: number): number;
sqrt(x: number): number;
log(x: number, base: number): number;
}
6 changes: 6 additions & 0 deletions examples/src/interfaces/ISimpleCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface ISimpleCalculator {
plus(x: number, y: number): number;
minus(x: number, y: number): number;
multiplies(x: number, y: number): number;
divides(x: number, y: number): number;
}
4 changes: 4 additions & 0 deletions examples/src/interfaces/IStatisticsCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface IStatisticsCalculator {
mean(...values: number[]): number;
stdev(...values: number[]): number;
}
18 changes: 18 additions & 0 deletions examples/src/providers/CalculatorBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Driver } from "tgrid";

import { ICalcConfig } from "../interfaces/ICalcConfig";
import { ICalcEventListener } from "../interfaces/ICalcEventListener";

export abstract class CalculatorBase {
public constructor(
private readonly config: ICalcConfig,
private readonly listener: Driver<ICalcEventListener>,
) {}

protected compute(type: string, input: number[], output: number): number {
const pow: number = Math.pow(10, this.config.precision);
output = Math.round(output * pow) / pow;
this.listener.on({ type, input, output }).catch(() => {});
return output;
}
}
25 changes: 25 additions & 0 deletions examples/src/providers/CompositeCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Driver } from "tgrid";

import { ICalcConfig } from "../interfaces/ICalcConfig";
import { ICalcEventListener } from "../interfaces/ICalcEventListener";
import { ICompositeCalculator } from "../interfaces/ICompositeCalculator";
import { ScientificCalculator } from "./ScientificCalculator";
import { SimpleCalculator } from "./SimpleCalculator";
import { StatisticsCalculator } from "./StatisticsCalculator";

export class CompositeCalculator
extends SimpleCalculator
implements ICompositeCalculator
{
public readonly scientific: ScientificCalculator;
public readonly statistics: StatisticsCalculator;

public constructor(
config: ICalcConfig,
listener: Driver<ICalcEventListener>,
) {
super(config, listener);
this.scientific = new ScientificCalculator(config, listener);
this.statistics = new StatisticsCalculator(config, listener);
}
}
17 changes: 17 additions & 0 deletions examples/src/providers/ScientificCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { IScientificCalculator } from "../interfaces/IScientificCalculator";
import { CalculatorBase } from "./CalculatorBase";

export class ScientificCalculator
extends CalculatorBase
implements IScientificCalculator
{
public pow(x: number, y: number): number {
return this.compute("pow", [x, y], Math.pow(x, y));
}
public sqrt(x: number): number {
return this.compute("sqrt", [x], Math.sqrt(x));
}
public log(x: number, base: number): number {
return this.compute("log", [x, base], Math.log(x) / Math.log(base));
}
}
20 changes: 20 additions & 0 deletions examples/src/providers/SimpleCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ISimpleCalculator } from "../interfaces/ISimpleCalculator";
import { CalculatorBase } from "./CalculatorBase";

export class SimpleCalculator
extends CalculatorBase
implements ISimpleCalculator
{
public plus(x: number, y: number): number {
return this.compute("plus", [x, y], x + y);
}
public minus(x: number, y: number): number {
return this.compute("minus", [x, y], x - y);
}
public multiplies(x: number, y: number): number {
return this.compute("multiplies", [x, y], x * y);
}
public divides(x: number, y: number): number {
return this.compute("divides", [x, y], x / y);
}
}
17 changes: 17 additions & 0 deletions examples/src/providers/StatisticsCalculator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { IStatisticsCalculator } from "../interfaces/IStatisticsCalculator";
import { CalculatorBase } from "./CalculatorBase";

export class StatisticsCalculator
extends CalculatorBase
implements IStatisticsCalculator
{
public mean(...values: number[]): number {
const sum: number = values.reduce((x, y) => x + y);
return this.compute("mean", values, sum / values.length);
}
public stdev(...values: number[]): number {
const mean: number = values.reduce((x, y) => x + y) / values.length;
const sum: number = values.reduce((x, y) => x + Math.pow(y - mean, 2));
return this.compute("stdev", values, Math.sqrt(sum / values.length));
}
}
31 changes: 31 additions & 0 deletions examples/src/websocket/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Driver, WebSocketConnector } from "tgrid";

import { ICalcConfig } from "../interfaces/ICalcConfig";
import { ICalcEvent } from "../interfaces/ICalcEvent";
import { ICalcEventListener } from "../interfaces/ICalcEventListener";
import { ICompositeCalculator } from "../interfaces/ICompositeCalculator";

export const webSocketClientMain = async () => {
const stack: ICalcEvent[] = [];
const listener: ICalcEventListener = {
on: (evt: ICalcEvent) => stack.push(evt),
};
const connector: WebSocketConnector<
ICalcConfig,
ICalcEventListener,
ICompositeCalculator
> = new WebSocketConnector(
{ precision: 2 }, // header
listener, // provider for remote server
);
await connector.connect("ws://127.0.0.1:37000/composite");

const remote: Driver<ICompositeCalculator> = connector.getDriver();
await remote.plus(10, 20); // returns 30
await remote.multiplies(3, 4); // returns 12
await remote.divides(5, 3); // returns 1.67
await remote.scientific.sqrt(2); // returns 1.41
await remote.statistics.mean(1, 3, 9); // returns 4.33

console.log(stack);
};
12 changes: 12 additions & 0 deletions examples/src/websocket/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { webSocketClientMain } from "./client";
import { webSocketServerMain } from "./server";

const main = async (): Promise<void> => {
const server = await webSocketServerMain();
await webSocketClientMain();
await server.close();
};
main().catch((exp) => {
console.error(exp);
process.exit(-1);
});
48 changes: 48 additions & 0 deletions examples/src/websocket/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Driver, WebSocketAcceptor, WebSocketServer } from "tgrid";

import { ICalcConfig } from "../interfaces/ICalcConfig";
import { ICalcEventListener } from "../interfaces/ICalcEventListener";
import { CompositeCalculator } from "../providers/CompositeCalculator";
import { ScientificCalculator } from "../providers/ScientificCalculator";
import { SimpleCalculator } from "../providers/SimpleCalculator";
import { StatisticsCalculator } from "../providers/StatisticsCalculator";

export const webSocketServerMain = async () => {
const server: WebSocketServer<
ICalcConfig,
| CompositeCalculator
| SimpleCalculator
| StatisticsCalculator
| ScientificCalculator,
ICalcEventListener
> = new WebSocketServer();
await server.open(
37_000,
async (
acceptor: WebSocketAcceptor<
ICalcConfig,
| CompositeCalculator
| SimpleCalculator
| StatisticsCalculator
| ScientificCalculator,
ICalcEventListener
>,
) => {
// LIST UP PROPERTIES
const config: ICalcConfig = acceptor.header;
const listener: Driver<ICalcEventListener> = acceptor.getDriver();

// ACCEPT OR REJECT
if (acceptor.path === "/composite")
await acceptor.accept(new CompositeCalculator(config, listener));
else if (acceptor.path === "/simple")
await acceptor.accept(new SimpleCalculator(config, listener));
else if (acceptor.path === "/statistics")
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.`);
},
);
return server;
};
Loading

0 comments on commit 71c8f37

Please sign in to comment.