Skip to content

i_zh_快速开始

huangjizhong edited this page Nov 4, 2023 · 4 revisions

快速开始

项目目录结构

image

  • 以聊天demo作为示例
  • 基本配置文件在config/sys目录下。master.ts为master服务器端口配置,servers.ts为开发者自定义的服务器配置,route.ts为通信消息列表。增加服务器只需要在servers.ts中添加对应配置即可,所有的通信消息必须在route.ts中。
  • servers 目录为通信消息入口。如 chat 表示聊天类型服务器,handler目录下接收客户端消息,remote目录下接收服务器之间的rpc调用消息。客户端发送chat.main.chat消息,服务器将会在servers/chat/handler/main.ts文件中的chat方法处收到消息,收到消息后调用next()即可发送数据给客户端。开发者调用 app.rpc("chat-server-1").chat.main.offline(),将会在servers/chat/remote/main.ts文件中的offline方法处收到消息。
  • app.ts为程序入口文件
  • 主动发送消息:
    1. 前端服使用app.sendMsgByUid()app.sendAll()
    2. 后端服使用app.sendMsgByUidSid()app.sendMsgByGroup()

master服务器

master服务器(即master.ts)读取配置文件,启动所配置的服务器集群,并对所有服务器进行管理。逻辑服务器启动后向master注册,通过master认识其他逻辑服并建立socket连接进行通信。

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

逻辑服务器

逻辑服务器(即servers.ts)是开发者编写代码的服务器集群。其中 frontend(需同时提供clientPort) 参数表示该服务器是客户端可连接的,即前端服务器。而没有该参数的服务器即后端服务器,不允许客户端连接。

{
    "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, },
        ],
    }
}

如果服务器进程特别多,则:

{
    "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 },
        ],
    }
}

可以简写为:

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

根据port参数解析

路由

  • 当客户端给后端服务器发消息时,需要提供路由函数以决定该消息发到哪个服务器。如下:
app.route("chat", function (session: Session) {
    return session.get("chatServerId");
});

rpc调用

let res = await this.app.rpc("connector-server-1", false).connector.main.test(msg);

1、connector-server-1 表示被调用的服务器。false表示被调用处需要返回消息,否则会触发超时错误。connector为服务器类型,main为文件名,test为方法名。
2、connector-server-1 如果为 * ,则是所有 connector类型的服务器都会被调用,此时,被调用方无法返回消息。
3、rpc调用的消息编码为 json
4、rpc调用有完整的代码提示,只需要填写声明文件,可参考项目代码,如下:

declare global {
    interface Rpc {
        connector: {
            main: Remote,
        }
    }
}

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

Rpc中的connector表示服务器类型,main表示文件名,Remote表示main文件中导出的default

Session类

session是与客户端socket绑定的,session中存着两个重要字段,uidsid,sid是前端服务器的名字,uid是socket连接绑定的唯一标识(前端服务器中调用session.bind()方法,绑定唯一uid),服务器主动向客户端发消息时,依据这两个字段来定位客户端。session中可通过set()get()方法存储自定义信息。后端服务器中的session是前端服务器在每次转发消息时对前端session的复制(所以不建议在session中存储过多信息),后端自定义存储后必须调用apply()方法,才能转存到前端服务器,或者rpc到前端服调用app.getSession()方法获得session,再进行修改。注意:session在调用set时会触发内部将session转为Buffer的操作,如果get某值并修改后没有重新set,则此修改不反映在后端服