samchon / tgrid

TypeScript RPC (Remote Procedure Call) for WebSocket and Worker protocols
https://tgrid.com/
MIT License
141 stars 19 forks source link

Basic Component - Communicator #3

Closed samchon closed 5 years ago

samchon commented 5 years ago

Outline

Communicator, a basic component, taking full charge of network communication.

sequence

The message structure for RFC (Remote Function Call) would be represented such like below and those structured data would be sent to the remote system like the top sequence diagram.

namespace tgrid.components
{
    // Message would be one of them.
    export type Invoke = IFunction | IReturn;

    export interface IFunction
    {
        uid: number; // identifier
        listener: string; // function (sometimes capsuled in objects) to call
        parameters: IParameter[]; // parameters for the function
    }
    export interface IParameter
    {
        type: string;
        value: any;
    }

    export interface IReturn
    {
        uid: number; // identifier
        success: boolean; // true -> return, false -> exception
        value: any | undefined; // returned value or thrown exception
    }
}

Communicator

The Communicator class would provide common features for RFC (Remote Function Call). Network communication of each protocol, they would be implemented in each protocol module by extending the Communicator class.

namespace tgrid.components
{
    export abstract class Communicator<Provider extends object>
    {
        /* ----------------------------------------------------------------
            CONSTRUCTORS
        ---------------------------------------------------------------- */
        /**
         * Initializer Constructor.
         * 
         * @param provider An object providing functions for the remote system.
         */
        protected constructor(provider?: Provider);

        /**
         * Destruct the communicator.
         * 
         * A destructor function should be called when the network communication has closed. 
         * It would destroy all RFC (function calls to the remote system, via the 
         * `Driver<Controller>`).
         * 
         * @param error An error instance to be thrown to the all remote functions that are 
         *              not returned yet.
         */
        protected destructor(error?: Error): Promise<void>;

        /* ----------------------------------------------------------------
            ACCESSORS
        ---------------------------------------------------------------- */
        /**
         * Get driver for remote controller.
         * 
         * The `Controller` is an interface who defines provided functions from the remote 
         system. The `Driver` is an object who makes to call remote functions, defined in the 
         * `Controller` and provided by `Provider` in the remote system, possible.
         * 
         * @return A driver for the remote controller.
         */
        public getDriver<Controller extends object>(): Driver<Controller>;

        /**
         * Join connection.
         * 
         * Wait until the connection to be closed (until `CommunicatorBase.desturctor()` called).
         */
        public join(): Promise<void>;

        /* ----------------------------------------------------------------
            COMMUNICATORS
        ---------------------------------------------------------------- */
        /**
         * Data Replier.
         * 
         * A function should be called when data has come from the remote system. 
         * 
         * When you receive a message from the remote system, then parse the message with your
         * special protocol and convert it to be an *Invoke* object. After that conversion, call 
         * this method.
         * 
         * @param invoke Structured data converted by your special protocol.
         */
        protected replyData(invoke: Invoke): void;

        /** 
         * A function sending data to the remote system.
         */
        protected abstract sendData(invoke: Invoke): void;

        /**
         * A predicator inspects whether the *network communication* is ready.
         */
        protected abstract inspectReady(): Error | null;
    }
}
samchon commented 5 years ago

Need not to separate CommunicatorBase and Communicator. Unite them to CommunicatorBase and rename the class to Communicator. Also make users to extends the Communicator class.