Skip to content

Commit

Permalink
Merge pull request #71 from samchon/features/websocket
Browse files Browse the repository at this point in the history
Refactor names of WebSockeet related classes.
  • Loading branch information
samchon authored May 6, 2024
2 parents 9f23125 + 1a97b8b commit a821982
Show file tree
Hide file tree
Showing 32 changed files with 234 additions and 191 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ However, whatever [Grid Computing](#12-grid-computing) and *Remote Function Call

#### [`composite-calculator/server.ts`](https://github.com/samchon/tgrid.examples/blob/master/src/projects/composite-calculator/server.ts)
```typescript
import { WebServer } from "tgrid/protocols/web";
import { WebSocketServer } from "tgrid/protocols/web";
import { CompositeCalculator } from "../../providers/Calculator";

async function main(): Promise<void>
{
const server: WebServer<object, CompositeCalculator> = new WebServer();
const server: WebSocketServer<object, CompositeCalculator> = new WebSocketServer();
await server.open(10102, async acceptor =>
{
await acceptor.accept(new CompositeCalculator());
Expand All @@ -65,7 +65,7 @@ main();

#### [`composite-calculator/client.ts`](https://github.com/samchon/tgrid.examples/blob/master/src/projects/composite-calculator/client.ts)
```typescript
import { WebConnector } from "tgrid/protocols/web/WebConnector";
import { WebSocketConnector } from "tgrid/protocols/web/WebSocketConnector";
import { Driver } from "tgrid/components/Driver";

import { ICalculator } from "../../controllers/ICalculator";
Expand All @@ -75,7 +75,7 @@ async function main(): Promise<void>
//----
// CONNECTION
//----
const connector: WebConnector<null, null> = new WebConnector(null, null);
const connector: WebSocketConnector<null, null> = new WebSocketConnector(null, null);
await connector.connect("ws://127.0.0.1:10102");

//----
Expand Down Expand Up @@ -166,7 +166,7 @@ Let's assume a situation; There's a distributed processing system build by tradi
Thus, with **TGrid** and [Remote Function Call](#13-remote-function-call), you can adapt compilation and type checking on the network system. It helps you to develop a network system safely and conveniently. Let's close this chapter with an example of *Safey Implementation*.
```typescript
import { WebConnector } from "tgrid/protocols/web/WebConnector"
import { WebSocketConnector } from "tgrid/protocols/web/WebSocketConnector"
import { Driver } from "tgrid/components/Driver";
interface ICalculator
Expand All @@ -184,7 +184,7 @@ async function main(): Promise<void>
//----
// CONNECTION
//----
const connector: WebConnector<null, null> = new WebConnector(null, null);
const connector: WebSocketConnector<null, null> = new WebSocketConnector(null, null);
await connector.connect("ws://127.0.0.1:10101");
//----
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tgrid",
"version": "0.11.0",
"version": "1.0.0-dev.20240507",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Communicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Invoke } from "./Invoke";
* The basic communicator.
*
* The `Communicator` is an abstract class taking full charge of network communication.
* Protocolized communicators like {@link WebConnector} are realized by extending this
* Protocolized communicators like {@link WebSocketConnector} are realized by extending this
* `Communicator` class.
*
* You want to make your own communicator using special protocol, extends this `Communicator`
Expand Down
4 changes: 2 additions & 2 deletions src/protocols/internal/IHeaderWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* @hidden
* @internal
*/
export interface IHeaderWrapper<Headers> {
header: Headers;
}

/**
* @hidden
* @internal
*/
export namespace IHeaderWrapper {
export function wrap<Header>(header: Header): IHeaderWrapper<Header> {
Expand Down
2 changes: 1 addition & 1 deletion src/protocols/internal/once.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* @hidden
* @internal
*/
export function once<Func>(handler: Func): Func {
let called: boolean = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ import type WebSocket from "ws";
import { Invoke } from "../../components/Invoke";
import { AcceptorBase } from "../internal/AcceptorBase";
import { IHeaderWrapper } from "../internal/IHeaderWrapper";
import { WebError } from "./WebError";
import { IWebCommunicator } from "./internal/IWebCommunicator";
import { WebSocketError } from "./WebSocketError";
import { IWebSocketCommunicator } from "./internal/IWebSocketCommunicator";

/**
* Web Socket Acceptor.
*
* - available only in the NodeJS.
*
* The `WebAcceptor` is a communicator class interacting with the remote (web socket) client using
* The `WebSocketAcceptor` is a communicator class interacting with the remote (web socket) client using
* [RFC](https://github.com/samchon/tgrid#13-remote-function-call) (Remote Function Call). The
* `WebAcceptor` objects are always created by the {@link WebServer} class whenever a remote client
* `WebSocketAcceptor` objects are always created by the {@link WebSocketServer} class whenever a remote client
* connects to its server.
*
* To accept connection and start interaction with the remote client, call the {@link accept}
* method with special `Provider`. After the {@link accept acceptance}, don't forget to closing the
* connection after your busines has been completed. Otherwise, you don't want to accept but reject
* the connection, call the {@link reject} method.
*
* Also, when declaring this {@link WebAcceptor} type, you've to define two template arguments,
* Also, when declaring this {@link WebSocketAcceptor} type, you've to define two template arguments,
* *Header* and *Provider*. The *Header* type repersents an initial data gotten from the remote
* client after the connection. I hope you and client not to omit it and utilize it as an
* activation tool to enhance security.
Expand All @@ -37,13 +37,13 @@ import { IWebCommunicator } from "./internal/IWebCommunicator";
* @template Remote Type of features supported by remote system, used for {@link getDriver} function.
* @author Jeongho Nam - https://github.com/samchon
*/
export class WebAcceptor<
export class WebSocketAcceptor<
Header,
Provider extends object | null,
Remote extends object | null,
>
extends AcceptorBase<Header, Provider, Remote>
implements IWebCommunicator
implements IWebSocketCommunicator
{
/**
* @hidden
Expand All @@ -65,16 +65,18 @@ export class WebAcceptor<
>(
request: http.IncomingMessage,
socket: WebSocket,
handler?: (acceptor: WebAcceptor<Header, Provider, Remote>) => Promise<any>,
handler?: (
acceptor: WebSocketAcceptor<Header, Provider, Remote>,
) => Promise<any>,
): void {
socket.once("message", async (data: WebSocket.Data) => {
// @todo: custom code is required
if (typeof data !== "string") socket.close();
else
try {
const wrapper: IHeaderWrapper<Header> = JSON.parse(data as string);
const acceptor: WebAcceptor<Header, Provider, Remote> =
new WebAcceptor(request, socket, wrapper.header);
const acceptor: WebSocketAcceptor<Header, Provider, Remote> =
new WebSocketAcceptor(request, socket, wrapper.header);
if (handler !== undefined) await handler(acceptor);
} catch (exp) {
socket.close();
Expand Down Expand Up @@ -111,7 +113,7 @@ export class WebAcceptor<
const ret: Promise<void> = this.join();

// DO CLOSE
this.state_ = WebAcceptor.State.CLOSING;
this.state_ = WebSocketAcceptor.State.CLOSING;
if (code === 1000) this.socket_!.close();
else this.socket_!.close(code!, reason!);

Expand All @@ -124,7 +126,7 @@ export class WebAcceptor<
*/
protected async destructor(error?: Error): Promise<void> {
await super.destructor(error);
this.state_ = WebAcceptor.State.CLOSED;
this.state_ = WebSocketAcceptor.State.CLOSED;
}

/* ----------------------------------------------------------------
Expand All @@ -151,14 +153,14 @@ export class WebAcceptor<
*
* List of values are such like below:
*
* - `REJECTING`: The {@link WebAcceptor.reject} method is on running.
* - `NONE`: The {@link WebAcceptor} instance is newly created, but did nothing yet.
* - `ACCEPTING`: The {@link WebAcceptor.accept} method is on running.
* - `REJECTING`: The {@link WebSocketAcceptor.reject} method is on running.
* - `NONE`: The {@link WebSocketAcceptor} instance is newly created, but did nothing yet.
* - `ACCEPTING`: The {@link WebSocketAcceptor.accept} method is on running.
* - `OPEN`: The connection is online.
* - `CLOSING`: The {@link WebAcceptor.close} method is on running.
* - `CLOSING`: The {@link WebSocketAcceptor.close} method is on running.
* - `CLOSED`: The connection is offline.
*/
public get state(): WebAcceptor.State {
public get state(): WebSocketAcceptor.State {
return this.state_;
}

Expand All @@ -170,22 +172,22 @@ export class WebAcceptor<
*/
public async accept(provider: Provider): Promise<void> {
// VALIDATION
if (this.state_ !== WebAcceptor.State.NONE)
if (this.state_ !== WebSocketAcceptor.State.NONE)
throw new DomainError(
"Error on WebAcceptor.accept(): you've already accepted (or rejected) the connection.",
"Error on WebSocketAcceptor.accept(): you've already accepted (or rejected) the connection.",
);

// PREPARE ASSETS
this.state_ = WebAcceptor.State.ACCEPTING;
this.state_ = WebSocketAcceptor.State.ACCEPTING;
this.provider_ = provider;

// REGISTER EVENTS
this.socket_.on("message", this._Handle_message.bind(this));
this.socket_.on("close", this._Handle_close.bind(this));
this.socket_.send(WebAcceptor.State.OPEN.toString());
this.socket_.send(WebSocketAcceptor.State.OPEN.toString());

// FINISHED
this.state_ = WebAcceptor.State.OPEN;
this.state_ = WebSocketAcceptor.State.OPEN;
}

/**
Expand All @@ -198,13 +200,13 @@ export class WebAcceptor<
*/
public async reject(status?: number, reason?: string): Promise<void> {
// VALIDATION
if (this.state_ !== WebAcceptor.State.NONE)
if (this.state_ !== WebSocketAcceptor.State.NONE)
throw new DomainError(
"You've already accepted (or rejected) the connection.",
);

// SEND CLOSING FRAME
this.state_ = WebAcceptor.State.REJECTING;
this.state_ = WebSocketAcceptor.State.REJECTING;
this.socket_.close(status, reason);

// FINALIZATION
Expand Down Expand Up @@ -235,8 +237,8 @@ export class WebAcceptor<
* @hidden
*/
private async _Handle_close(code: number, reason: string): Promise<void> {
const error: WebError | undefined =
code !== 100 ? new WebError(code, reason) : undefined;
const error: WebSocketError | undefined =
code !== 100 ? new WebSocketError(code, reason) : undefined;

await this.destructor(error);
}
Expand All @@ -245,9 +247,9 @@ export class WebAcceptor<
/**
*
*/
export namespace WebAcceptor {
export namespace WebSocketAcceptor {
/**
* Current state of the {@link WebAcceptor}.
* Current state of the {@link WebSocketAcceptor}.
*/
export import State = AcceptorBase.State;
}
Loading

0 comments on commit a821982

Please sign in to comment.