Skip to content

i_en_quick_start

huangjizhong edited this page Nov 4, 2023 · 5 revisions

Quick start

Project Directory Structure

image

  • Take chat demo as an example
  • The basic configuration file is in the config/sys directory. master.ts is the master server port configuration, servers.ts is the developer-defined server configuration, and route.ts is the communication message list. To add a server, you only need to add the corresponding configuration in servers.ts, and all communication messages must be in route.ts.
  • The servers directory is the entry for communication messages. For example, chat represents a chat type server. Client messages are received under the handler directory, and rpc call messages between servers are received under the remote directory. The client sends a chat.main.chat message, the server will receive the message at the chat method in the servers/chat/handler/main.ts file, and call next() after receiving the message, data can be sent to the client. Developers call app.rpc("chat-server-1").chat.main.offline(), they will receive it in the offline method in the servers/chat/remote/main.ts file.
  • app.ts is the program entry file
  • Actively send messages:
    1. The frontend server uses app.sendMsgByUid(), app.sendAll().
    2. The backend server uses app.sendMsgByUidSid(), app.sendMsgByGroup().

Master Server

The master server (ie master.ts) reads the configuration file, starts the configured server cluster, and manages all servers. After the logical server is started, it registers with the master, recognizes other logical servers and establishes a socket connection for communication.

{
    "development": {
        "id": "master-server-1", "host": "127.0.0.1", "port": 3005
    },
    "production": {
        "id": "master-server-1", "host": "127.0.0.1", "port": 3005
    }
}

Logic Server

The logical server (ie servers.ts) is a server cluster where developers write code. The frontend (clientPort must be provided at the same time) parameter indicates that the server is client-connectable, that is, the frontend server. The server without this parameter is the backend server, and client connections are not allowed.

{
    "development": {
        "connector": [
            { "id": "connector-server-1", "host": "127.0.0.1", "port": 4021, "frontend": true, "clientPort": 4001, },
        ],
    },
    "production": {
        "connector": [
            { "id": "connector-server-1", "host": "127.0.0.1", "port": 4021, "frontend": true, "clientPort": 4001, },
        ],
    }
}

If there are too many server processes, then:

{
    "development": {
        "connector": [
            { "id": "connector-server-1", "host": "127.0.0.1", "port": 4021 },
            { "id": "connector-server-2", "host": "127.0.0.1", "port": 4022 },
            { "id": "connector-server-3", "host": "127.0.0.1", "port": 4023 },
        ],
    }
}

Can be abbreviated as:

{
    "development": {
        "connector": [
            { "id": "connector-server-", "idStart": 1, "host": "127.0.0.1", "port": [4021, 4023] },
        ],
    }
}

According to the port parameter analysis

Routing

  • When the client sends a message to the backend server, it needs to provide a routing function to determine which server the message is sent to. as follows:
app.route("chat", function (session: Session) {
    return session.get("chatServerId");
});

Rpc Call

let res = await this.app.rpc("connector-server-1", false).connector.main.test(msg);
  1. connector-server-1 represents the server be rpc called. false means the message receiver needs to response, otherwise it will trigger a timeout.connector means the serverType, main means the filename, test means the method.
  2. If connector-server-1 is *, then all connector serverType will be called. At this point, the called party cannot return a message.
  3. The message of the rpc call is encoded as json.
  4. There is a complete code prompt for rpc call, just fill in the declaration file, you can refer to the project code, as follows:
    declare global {
        interface Rpc {
            connector: {
                main: Remote,
            }
        }
    }

    export default class Remote {
        constructor(app: Application) {
        }
        test(msg: string) {
            console.log("rpcMsg", msg);
        }
    }

connector in Rpc indicates the server type, main indicates the file name, and Remote indicates the default class exported from the main file.

Session Class

The session is bound to the client socket. There are two important fields in the session, uid and sid, sid is the name of the frontend server, and uid is the unique identifier of the socket connection binding (session.bind() method is called in the frontend server to bind a unique uid). When the server actively sends a message to the client, it locates the client based on these two fields. Customized information can be stored in the session through the set() and get() methods. The session in the backend server is a copy of the frontend session every time the frontend server forwards a message (so it is not recommended to store too much information in the session). After the backend custom storage, the apply() method must be called to transfer to the frontend server, or rpc to the frontend server to call the app.getSession() method to get the session, and then modify. Note: When session calls set, it will trigger the internal conversion of session to Buffer. If you get a value and modify it without re-set, this modification will not be reflected in the backend server