@xiaoguomeiyitian/core 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +250 -0
- package/dist/lib_linux_20.jsc +0 -0
- package/dist/lib_linux_22.jsc +0 -0
- package/dist/lib_win32_20.jsc +0 -0
- package/dist/lib_win32_22.jsc +0 -0
- package/package.json +3 -2
package/README.md
ADDED
@@ -0,0 +1,250 @@
|
|
1
|
+
# 框架概述
|
2
|
+
|
3
|
+
一个基于实体模型的前后端数据同步框架,支持热更新、自动同步和持久化存储,通过 RPC 调用实现分布式部署
|
4
|
+
|
5
|
+
## 特性
|
6
|
+
|
7
|
+
- 🔄 **热更新**: 支持通过 loadfile 动态更新实体类
|
8
|
+
- 🚀 **自动同步**: 后端实体数据自动同步至前端
|
9
|
+
- 💾 **自动存储**: 带有 @save 标记的属性自动保存至数据库
|
10
|
+
- 🔗 **双向调用**: 支持前后端之间的实体方法互相调用
|
11
|
+
- 📝 **声明式配置**: 通过注释标记实现属性的配置管理
|
12
|
+
- 🌐 **分布式部署**: 基于 RPC 调用的分布式架构
|
13
|
+
- 📦 **数据持久化**: 支持 MongoDB 存储和 Redis 缓存
|
14
|
+
- 💽 **进程缓存**: 使用 LevelDB 进程实体数据保存,支持进程崩溃后数据恢复
|
15
|
+
- 🔍 **在线调试**: 支持实时调试和性能分析
|
16
|
+
- HeapProfiler: 查看 V8 引擎内存快照
|
17
|
+
- Profiler: 统计 CPU 调用信息
|
18
|
+
- GCProfiler: 监控垃圾回收统计
|
19
|
+
|
20
|
+
## cli
|
21
|
+
|
22
|
+
core dbg 在线调试
|
23
|
+
core defs 生成类型定义
|
24
|
+
core func 生成调用函数列表
|
25
|
+
|
26
|
+
## 实体定义示例
|
27
|
+
|
28
|
+
```typescript
|
29
|
+
export interface Player {
|
30
|
+
/** 唯一编号 @save */
|
31
|
+
id?: string;
|
32
|
+
/** @default 127.0.0.1 @server @save */
|
33
|
+
ip?: string;
|
34
|
+
/** 账号 @save */
|
35
|
+
account?: string
|
36
|
+
/** 服务器id @save */
|
37
|
+
sid?: number;
|
38
|
+
/** 创号时间 @save */
|
39
|
+
cTime?: number;
|
40
|
+
/** 昵称 @default nickname @save */
|
41
|
+
nickname?: string;
|
42
|
+
/** 公会id @default 0 @save */
|
43
|
+
ghId?: string;
|
44
|
+
}
|
45
|
+
```
|
46
|
+
|
47
|
+
属性标记说明
|
48
|
+
@save: 标记需要持久化存储的属性
|
49
|
+
@server: 标记仅在服务器端存在的属性(不会同步到客户端)
|
50
|
+
@default value: 设置属性的默认值
|
51
|
+
|
52
|
+
## 示例
|
53
|
+
|
54
|
+
#### 同步实体到前端
|
55
|
+
|
56
|
+
```typescript
|
57
|
+
export class Player extends BaseEntity implements PlayerServer {
|
58
|
+
/** 创建实体时调用 */
|
59
|
+
async onCreate() {
|
60
|
+
this.syncEntity();//同步实体到前端
|
61
|
+
}
|
62
|
+
/** 实体销毁时调用 */
|
63
|
+
async onDestroy() {
|
64
|
+
|
65
|
+
}
|
66
|
+
/** 实体属性变化时调用 */
|
67
|
+
async onPropChange(prop: string, value: any) {
|
68
|
+
|
69
|
+
}
|
70
|
+
}
|
71
|
+
```
|
72
|
+
|
73
|
+
#### 前端调用后端
|
74
|
+
|
75
|
+
```typescript
|
76
|
+
export class Player extends Entity implements PlayerClient {
|
77
|
+
server: PlayerServer;
|
78
|
+
/** 修改头像 */
|
79
|
+
modifyNickname(nickname: string) {
|
80
|
+
//调用后端player实体 modifyNickname 修改实体昵称
|
81
|
+
this.server.modifyNickname({ nickname: nickname });
|
82
|
+
}
|
83
|
+
/** 收到断线重连 */
|
84
|
+
async onReConnection(msg: MsgonReConnection) {
|
85
|
+
if (msg.roomtype == 0) return G.removeLoading();
|
86
|
+
console.log("需要断线重连");
|
87
|
+
}
|
88
|
+
/** 当属性更新 */
|
89
|
+
onPropChange(prop, oldVal, value) {
|
90
|
+
console.log(prop, oldVal, value);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
```
|
94
|
+
|
95
|
+
#### 后端调用前端
|
96
|
+
|
97
|
+
```typescript
|
98
|
+
export class Player extends BaseEntity implements PlayerServer {
|
99
|
+
client: PlayerClient;
|
100
|
+
async onCreate() {
|
101
|
+
//调用前端player实体的 onReConnection 函数通知前端是否断线重连
|
102
|
+
this.client.onReConnection({ roomtype: 0, url: "" });
|
103
|
+
}
|
104
|
+
async onDestroy() {
|
105
|
+
|
106
|
+
}
|
107
|
+
/** 修改昵称 */
|
108
|
+
modifyNickname(msg: MsgmodifyNickname, call?: MsgCall<MsgmodifyNickname, any>) {
|
109
|
+
this.nickname = msg.nickname;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
```
|
113
|
+
后端收到前端调用 modifyNickname 函数,直接修改 this.nickname = msg.nickname 即可,
|
114
|
+
底层会把修改后的内容同步到前端和写入到数据库中。
|
115
|
+
底层会自动优化写入和同步逻辑,会在所有同步逻辑执行完毕异步逻辑发起之前进行同步和写入
|
116
|
+
|
117
|
+
#### RPC调用
|
118
|
+
|
119
|
+
```typescript
|
120
|
+
//hall进程中的player类
|
121
|
+
export class Player extends BaseEntity implements PlayerServer {
|
122
|
+
client: PlayerClient;
|
123
|
+
async onCreate() {
|
124
|
+
//rpc调用游戏服的RoomManage的getRoomtype获取玩家的房间id
|
125
|
+
const res = (await G.getRpc("RoomManager", server.surl).getRoomtype({ uid: this.id })).res;
|
126
|
+
//调用前端player实体的 onReConnection 函数通知前端是否断线重连
|
127
|
+
this.client.onReConnection({ roomtype: res.roomType, url: "" });
|
128
|
+
}
|
129
|
+
async onDestroy() {
|
130
|
+
|
131
|
+
}
|
132
|
+
}
|
133
|
+
//game进程的RoomManager类
|
134
|
+
export class RoomManager extends BaseEntity implements RoomManagerRpc {
|
135
|
+
/**根据玩家id获取房间类型 */
|
136
|
+
async getRoomtype(req: ReqgetRoomtype, call: DefaultCall<ReqgetRoomtype, ResgetRoomtype, any> = defaultCall): Promise<ApiReturn<ResgetRoomtype>> {
|
137
|
+
const room = this.getRoomByPlayerId(req.uid);
|
138
|
+
return call.succ({ roomType: room.roomType });
|
139
|
+
}
|
140
|
+
}
|
141
|
+
```
|
142
|
+
|
143
|
+
#### 热更新实体
|
144
|
+
|
145
|
+
```typescript
|
146
|
+
G.loadfile("./server/hall/Player.ts");
|
147
|
+
```
|
148
|
+
|
149
|
+
#### API
|
150
|
+
|
151
|
+
```typescript
|
152
|
+
export declare class Global {
|
153
|
+
/** cwd路径 */
|
154
|
+
_cwdDir: string;
|
155
|
+
event: EventEmitter;
|
156
|
+
entityDefs: any;
|
157
|
+
serviceProto: any;
|
158
|
+
serviceProtoServer: any;
|
159
|
+
constructor();
|
160
|
+
init(entityDefs: any, serviceProto: any, serviceProtoServer: any): Promise<void>;
|
161
|
+
/**获取某类实体属性的类型 */
|
162
|
+
getPropType(type: string, prop: string): any;
|
163
|
+
/**获取某类实体属性的默认值 */
|
164
|
+
getPropDefault(type: string, prop: string): any;
|
165
|
+
/**从redis读取数据 */
|
166
|
+
loadByRedis(type: string, id: string): Promise<any>;
|
167
|
+
/**数据写入到redis */
|
168
|
+
setToRedis(type: string, id: string, data: any): Promise<void>;
|
169
|
+
/**根据条件从mongo中查询单条实体数据*/
|
170
|
+
findOne(type: string, filter: any, keys?: string[]): Promise<any>;
|
171
|
+
/**根据条件从mongo中查询多条实体数据*/
|
172
|
+
find(type: string, filter: any, keys?: string[]): Promise<any>;
|
173
|
+
/**创建实体 单个进程只会创建一个相同id的实体*/
|
174
|
+
create(type: string, id?: string, cdata?: any): Promise<any>;
|
175
|
+
/**根据类型和id获取实体 */
|
176
|
+
get(type: string, id?: string): any;
|
177
|
+
/**获取rpc对象 */
|
178
|
+
getRpc(type: string, serverUrl: string): any;
|
179
|
+
/**获取某类实体属性的类型 */
|
180
|
+
getByType(type: string): any[];
|
181
|
+
/**加载某个文件夹下的所有文件 reChain 是否更新继承链上的其他实体 @param { boolean} reload 是否重新加载文件 默认:false */
|
182
|
+
loadAllFile(source: string, reChain?: boolean, reload?: boolean): void;
|
183
|
+
/**热更新某个文件 @param { boolean} reChain 是否更新继承链上的其他实体 @param { boolean} reload 是否重新加载文件 默认:true */
|
184
|
+
loadfile(filePath: string, reChain?: boolean, reload?: boolean): Promise<void>;
|
185
|
+
/**保存之前没有保存的dump数据*/
|
186
|
+
flushDumpData(): Promise<void>;
|
187
|
+
/** 获取V8 CPU调用统计信息,默认统计10秒钟 cwd/profile.cpuprofile*/
|
188
|
+
profiler(time?: number): void;
|
189
|
+
/** 获取V8 GC统计信息,默认统计10秒钟 */
|
190
|
+
profilerGC(time?: number): void;
|
191
|
+
/** 生成内存快照 cwd/heapSnapshot.heapsnapshot*/
|
192
|
+
profilerHeap(password: string): void;
|
193
|
+
}
|
194
|
+
export declare class Entity {
|
195
|
+
type: string; /** 实体类型 */
|
196
|
+
id: string; /** 实体id */
|
197
|
+
/** 连接列表 */
|
198
|
+
conns: WsConnection[];
|
199
|
+
constructor(type: string, id?: string);
|
200
|
+
/**获取属性类型 */
|
201
|
+
getPropType(prop: string): any;
|
202
|
+
/**获取未定义的数据默认值 */
|
203
|
+
getPropDefault(prop: string): any;
|
204
|
+
/**递归地设置对象中的值 */
|
205
|
+
setValueByPath(path: string[], value: any, type?: "inc" | "set" | "unset" | "push" | "pull", ext?: {
|
206
|
+
min?: number;
|
207
|
+
max?: number;
|
208
|
+
leng?: number;
|
209
|
+
}): void;
|
210
|
+
/**递归地获取对象中的值 */
|
211
|
+
getValueByPath(path: string[]): any;
|
212
|
+
/**保持数据至缓存 */
|
213
|
+
saveToDump(prop: string, value: any): Promise<void>;
|
214
|
+
/**属性变化 */
|
215
|
+
propChange(prop: string, value: any, key?: string): Promise<void>;
|
216
|
+
/**创建 */
|
217
|
+
create(): Promise<void>;
|
218
|
+
/**实体同步到客户端 */
|
219
|
+
syncEntity(conns?: WsConnection[]): void;
|
220
|
+
/**写入数据库 */
|
221
|
+
flush(): Promise<void>;
|
222
|
+
/**销毁 */
|
223
|
+
destroy(): Promise<void>;
|
224
|
+
/**添加定时器 */
|
225
|
+
addOneLoop(funcName: Function, time: number): number;
|
226
|
+
/**清除定时器 */
|
227
|
+
clearOneLoop(timeId: number): void;
|
228
|
+
/**添加循环 */
|
229
|
+
addLoop(funcName: Function, time: number): number;
|
230
|
+
/**清除循环 */
|
231
|
+
clearLoop(timeId: number): void;
|
232
|
+
/**清除所有定时器 */
|
233
|
+
clearAllLoop(): void;
|
234
|
+
onCreate(): void;
|
235
|
+
onPropChange(prop: string, value: any): void;
|
236
|
+
onDestroy(): void;
|
237
|
+
}
|
238
|
+
export declare class GenEntityDefs {
|
239
|
+
gen(filePath: string): void;
|
240
|
+
}
|
241
|
+
export declare class GenServiceFunc {
|
242
|
+
gen(fReadPath: string, fWritePath: string, types: string[]): void;
|
243
|
+
}
|
244
|
+
```
|
245
|
+
|
246
|
+
####
|
247
|
+
|
248
|
+
```typescript
|
249
|
+
|
250
|
+
```
|
package/dist/lib_linux_20.jsc
CHANGED
Binary file
|
package/dist/lib_linux_22.jsc
CHANGED
Binary file
|
package/dist/lib_win32_20.jsc
CHANGED
Binary file
|
package/dist/lib_win32_22.jsc
CHANGED
Binary file
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@xiaoguomeiyitian/core",
|
3
|
-
"version": "1.2.
|
3
|
+
"version": "1.2.3",
|
4
4
|
"main": "dist/index.js",
|
5
5
|
"types": "types/lib.d.ts",
|
6
6
|
"bin": {
|
@@ -10,7 +10,8 @@
|
|
10
10
|
"types/lib.d.ts",
|
11
11
|
"dist/index.js",
|
12
12
|
"dist/cli.js",
|
13
|
-
"dist/lib_*.jsc"
|
13
|
+
"dist/lib_*.jsc",
|
14
|
+
"README.md"
|
14
15
|
],
|
15
16
|
"scripts": {
|
16
17
|
"pull": "git stash && git pull && git stash pop",
|