@fastcar/template-microservices 1.0.0

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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/package.json +35 -0
  4. package/template/.prettierrc +9 -0
  5. package/template/.vscode/launch.json +183 -0
  6. package/template/README.md +1 -0
  7. package/template/package.json +47 -0
  8. package/template/resource/application-dev.yml +56 -0
  9. package/template/resource/application.yml +2 -0
  10. package/template/src/annotation/AuthServiceRole.ts +76 -0
  11. package/template/src/annotation/EnableHotConfig.ts +13 -0
  12. package/template/src/app-node.ts +94 -0
  13. package/template/src/app-pm2.ts +191 -0
  14. package/template/src/common/Code.ts +26 -0
  15. package/template/src/common/Constant.ts +28 -0
  16. package/template/src/common/Result.ts +40 -0
  17. package/template/src/common/TaskAsync.ts +17 -0
  18. package/template/src/hotconfig/ExampleConfigService.ts +29 -0
  19. package/template/src/hotconfig/HotConfigInterface.ts +43 -0
  20. package/template/src/middleware/checkForm.ts +20 -0
  21. package/template/src/middleware/checkLogin.ts +25 -0
  22. package/template/src/middleware/parseSession.ts +44 -0
  23. package/template/src/servers/base/BaseServer.ts +120 -0
  24. package/template/src/servers/base/common/BackSessionEntryController.ts +33 -0
  25. package/template/src/servers/base/common/RemoteController.ts +70 -0
  26. package/template/src/servers/base/service/BackSessionService.ts +97 -0
  27. package/template/src/servers/base/service/CenterClient.ts +457 -0
  28. package/template/src/servers/base/service/DataService.ts +85 -0
  29. package/template/src/servers/base/service/RouterService.ts +185 -0
  30. package/template/src/servers/center/app.ts +14 -0
  31. package/template/src/servers/center/controller/EntryController.ts +89 -0
  32. package/template/src/servers/center/controller/ServerController.ts +62 -0
  33. package/template/src/servers/center/service/ServerManager.ts +336 -0
  34. package/template/src/servers/chat/RoomHandler.ts +65 -0
  35. package/template/src/servers/chat/RoomService.ts +24 -0
  36. package/template/src/servers/chat/app.ts +11 -0
  37. package/template/src/servers/connector/app.ts +13 -0
  38. package/template/src/servers/connector/controller/AccountHandler.ts +80 -0
  39. package/template/src/servers/connector/controller/ChannelRemote.ts +63 -0
  40. package/template/src/servers/connector/middleware/forwardMsg.ts +54 -0
  41. package/template/src/servers/web/HelloController.ts +51 -0
  42. package/template/src/servers/web/SyncConfigService.ts +13 -0
  43. package/template/src/servers/web/app.ts +15 -0
  44. package/template/src/types/ClientSimpleSession.ts +3 -0
  45. package/template/src/types/ForwardRpcContext.ts +3 -0
  46. package/template/src/types/ReqSession.ts +8 -0
  47. package/template/src/types/ResultType.ts +5 -0
  48. package/template/src/types/ServerMeta.ts +48 -0
  49. package/template/src/types/SessionAttribute.ts +13 -0
  50. package/template/src/utils/ConnectorUtils.ts +25 -0
  51. package/template/src/utils/MicroservicesUtils.ts +101 -0
  52. package/template/src/utils/NetWork.ts +31 -0
  53. package/template/src/utils/SessionUtil.ts +46 -0
  54. package/template/test/connector-test.ts +64 -0
  55. package/template/test/hello.ts +71 -0
  56. package/template/tsconfig.json +39 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 william_zhong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # @fastcar/template-microservices
2
+
3
+ 基于 fastcar-core 的微服务应用模板
4
+
5
+ ## 简介
6
+
7
+ 这是一个用于快速搭建微服务架构的模板,包含多个服务模块,适用于构建分布式系统。
8
+
9
+ ## 特性
10
+
11
+ - 🚀 基于 [fastcar-core](https://www.npmjs.com/package/@fastcar/core) 框架
12
+ - 🏗️ 多服务模式(center、connector、chat、web)
13
+ - 🔗 内置 RPC 通信
14
+ - 📦 支持 TypeScript
15
+ - 🔄 支持 PM2 进程管理
16
+ - 🔌 支持 WebSocket
17
+
18
+ ## 服务模块
19
+
20
+ - **center**: 服务中心,提供服务注册与发现
21
+ - **connector**: 连接器服务,处理客户端连接
22
+ - **chat**: 聊天服务,处理实时消息
23
+ - **web**: Web 服务,提供 HTTP 接口
24
+ - **base**: 基础服务,提供公共功能
25
+
26
+ ## 使用方式
27
+
28
+ ### 安装依赖
29
+
30
+ ```bash
31
+ cd template
32
+ npm install
33
+ # 或者
34
+ yarn install
35
+ ```
36
+
37
+ ### 开发调试
38
+
39
+ ```bash
40
+ # 启动单个节点模式
41
+ npm run start-node
42
+
43
+ # 启动 PM2 管理模式
44
+ npm run start-pm2
45
+ ```
46
+
47
+ ### 编译项目
48
+
49
+ ```bash
50
+ npm run build
51
+ # 或者
52
+ yarn build
53
+ ```
54
+
55
+ ### 启动服务
56
+
57
+ ```bash
58
+ npm start
59
+ # 或者
60
+ yarn start
61
+ ```
62
+
63
+ ### 停止服务
64
+
65
+ ```bash
66
+ npm stop
67
+ # 或者
68
+ yarn stop
69
+ ```
70
+
71
+ ## 配置说明
72
+
73
+ 配置文件位于 `resource/` 目录:
74
+
75
+ - `application.yml` - 主配置
76
+ - `application-dev.yml` - 开发环境配置
77
+ - `ecosystem.config.yml` - PM2 配置
78
+
79
+ ## 项目结构
80
+
81
+ ```
82
+ template/
83
+ ├── src/
84
+ │ ├── annotation/ # 注解定义
85
+ │ ├── common/ # 公共代码
86
+ │ ├── middleware/ # 中间件
87
+ │ ├── servers/ # 服务目录
88
+ │ │ ├── base/ # 基础服务
89
+ │ │ ├── center/ # 服务中心
90
+ │ │ ├── chat/ # 聊天服务
91
+ │ │ ├── connector/ # 连接器服务
92
+ │ │ └── web/ # Web 服务
93
+ │ ├── types/ # 类型定义
94
+ │ ├── utils/ # 工具函数
95
+ │ ├── app-node.ts # 单节点入口
96
+ │ └── app-pm2.ts # PM2 入口
97
+ ├── resource/
98
+ │ ├── application.yml
99
+ │ ├── application-dev.yml
100
+ │ └── ecosystem.config.yml
101
+ ├── test/ # 测试文件
102
+ ├── package.json
103
+ ├── tsconfig.json
104
+ └── ecosystem.config.yml
105
+ ```
106
+
107
+ ## 依赖
108
+
109
+ - [@fastcar/core](https://www.npmjs.com/package/@fastcar/core) - 核心框架
110
+ - [@fastcar/koa](https://www.npmjs.com/package/@fastcar/koa) - Koa 集成
111
+ - [@fastcar/rpc](https://www.npmjs.com/package/@fastcar/rpc) - RPC 支持
112
+ - [@fastcar/server](https://www.npmjs.com/package/@fastcar/server) - 服务器支持
113
+ - [@fastcar/timer](https://www.npmjs.com/package/@fastcar/timer) - 定时器支持
114
+
115
+ ## 相关模板
116
+
117
+ - [@fastcar/template-web](../web) - Web 项目模板
118
+ - [@fastcar/template-static](../static) - 静态资源服务器模板
119
+ - [@fastcar/template-rpc](../rpc) - RPC 服务器模板
120
+ - [@fastcar/template-cos](../cos) - 对象存储服务模板
121
+
122
+ ## License
123
+
124
+ MIT
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@fastcar/template-microservices",
3
+ "version": "1.0.0",
4
+ "description": "基于 fastcar-core 的微服务应用模板",
5
+ "main": "index.js",
6
+ "keywords": [
7
+ "fastcar",
8
+ "microservices",
9
+ "template",
10
+ "typescript",
11
+ "nodejs"
12
+ ],
13
+ "author": "william_zhong",
14
+ "license": "MIT",
15
+ "homepage": "https://github.com/williamDazhangyu/fastcar-template#readme",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/williamDazhangyu/fastcar-template.git",
19
+ "directory": "microservices"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/williamDazhangyu/fastcar-template/issues"
23
+ },
24
+ "engines": {
25
+ "node": ">=16"
26
+ },
27
+ "files": [
28
+ "template",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "test": "echo \"Error: no test specified\" && exit 1"
34
+ }
35
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "tabWidth": 4,
3
+ "printWidth": 200,
4
+ "trailingComma": "es5",
5
+ "useTabs": true,
6
+ "jsonEnable": [
7
+ "json"
8
+ ]
9
+ }
@@ -0,0 +1,183 @@
1
+ {
2
+ // 使用 IntelliSense 了解相关属性。
3
+ // 悬停以查看现有属性的描述。
4
+ // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Run TS",
9
+ "type": "node",
10
+ "request": "launch",
11
+ "args": [
12
+ "${relativeFile}",
13
+ "serverType=web",
14
+ "serviceId=web-server-1"
15
+ ],
16
+ "cwd": "${workspaceRoot}",
17
+ "runtimeArgs": [
18
+ "-r",
19
+ "ts-node/register"
20
+ ],
21
+ "env": {
22
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
23
+ }
24
+ },
25
+ {
26
+ "name": "Run JS",
27
+ "type": "node",
28
+ "request": "launch",
29
+ "program": "${file}"
30
+ },
31
+ {
32
+ "name": "Run APP_NODE",
33
+ "type": "node",
34
+ "request": "launch",
35
+ "args": [
36
+ "${workspaceRoot}/src/app-node.ts"
37
+ ],
38
+ "cwd": "${workspaceRoot}",
39
+ "runtimeArgs": [
40
+ "-r",
41
+ "ts-node/register"
42
+ ],
43
+ "env": {
44
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
45
+ }
46
+ },
47
+ {
48
+ "name": "Run APP_PM2",
49
+ "type": "node",
50
+ "request": "launch",
51
+ "args": [
52
+ "${workspaceRoot}/src/app-pm2.ts"
53
+ ],
54
+ "cwd": "${workspaceRoot}",
55
+ "runtimeArgs": [
56
+ "-r",
57
+ "ts-node/register"
58
+ ],
59
+ "env": {
60
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
61
+ }
62
+ },
63
+ {
64
+ "name": "Run mocha",
65
+ "type": "node",
66
+ "request": "launch",
67
+ "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
68
+ "stopOnEntry": false,
69
+ "args": [
70
+ "${relativeFile}",
71
+ "--no-timeouts"
72
+ ],
73
+ "cwd": "${workspaceRoot}",
74
+ "runtimeExecutable": null,
75
+ "env": {
76
+ "NODE_ENV": "testing"
77
+ },
78
+ "runtimeArgs": [
79
+ "-r",
80
+ "ts-node/register"
81
+ ]
82
+ },
83
+ {
84
+ "type": "node",
85
+ "request": "attach",
86
+ "name": "DEBUG",
87
+ "address": "localhost",
88
+ "port": 2000,
89
+ "localRoot": "${workspaceFolder}",
90
+ "remoteRoot": "${workspaceFolder}"
91
+ },
92
+ {
93
+ "name": "Run CENTER-1",
94
+ "type": "node",
95
+ "request": "launch",
96
+ "args": [
97
+ "${workspaceRoot}/src/app-node.ts",
98
+ "serverType=center",
99
+ "serviceId=center-server-1"
100
+ ],
101
+ "cwd": "${workspaceRoot}",
102
+ "runtimeArgs": [
103
+ "-r",
104
+ "ts-node/register"
105
+ ],
106
+ "env": {
107
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
108
+ }
109
+ },
110
+ {
111
+ "name": "Run CENTER-2",
112
+ "type": "node",
113
+ "request": "launch",
114
+ "args": [
115
+ "${workspaceRoot}/src/app-node.ts",
116
+ "serverType=center",
117
+ "serviceId=center-server-2"
118
+ ],
119
+ "cwd": "${workspaceRoot}",
120
+ "runtimeArgs": [
121
+ "-r",
122
+ "ts-node/register"
123
+ ],
124
+ "env": {
125
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
126
+ }
127
+ },
128
+ {
129
+ "name": "Run WEB-1",
130
+ "type": "node",
131
+ "request": "launch",
132
+ "args": [
133
+ "${workspaceRoot}/src/app-node.ts",
134
+ "serverType=web",
135
+ "serviceId=web-server-1"
136
+ ],
137
+ "cwd": "${workspaceRoot}",
138
+ "runtimeArgs": [
139
+ "-r",
140
+ "ts-node/register"
141
+ ],
142
+ "env": {
143
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
144
+ }
145
+ },
146
+ {
147
+ "name": "Run WEB-2",
148
+ "type": "node",
149
+ "request": "launch",
150
+ "args": [
151
+ "${workspaceRoot}/src/app-node.ts",
152
+ "serverType=web",
153
+ "serviceId=web-server-2"
154
+ ],
155
+ "cwd": "${workspaceRoot}",
156
+ "runtimeArgs": [
157
+ "-r",
158
+ "ts-node/register"
159
+ ],
160
+ "env": {
161
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
162
+ }
163
+ },
164
+ {
165
+ "name": "Run CHAT-1",
166
+ "type": "node",
167
+ "request": "launch",
168
+ "args": [
169
+ "${workspaceRoot}/src/app-node.ts",
170
+ "serverType=chat",
171
+ "serviceId=chat-server-1"
172
+ ],
173
+ "cwd": "${workspaceRoot}",
174
+ "runtimeArgs": [
175
+ "-r",
176
+ "ts-node/register"
177
+ ],
178
+ "env": {
179
+ "TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.json"
180
+ }
181
+ },
182
+ ]
183
+ }
@@ -0,0 +1 @@
1
+ #fastcar-microservices
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@fastcar/template-microservices",
3
+ "version": "1.0.0",
4
+ "description": "微服务应用模板",
5
+ "engines": {
6
+ "node": ">=22"
7
+ },
8
+ "scripts": {
9
+ "start": "pm2 start ./resource/ecosystem.config.yml",
10
+ "stop": "pm2 stop ./resource/ecosystem.config.yml",
11
+ "delete": "pm2 delete ./resource/ecosystem.config.yml",
12
+ "build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
13
+ "start-node": "node -r ts-node/register ./src/app-node.ts",
14
+ "start-pm2": "node -r ts-node/register ./src/app-pm2.ts cmd=start",
15
+ "start-pm2-js": "node ./target/app-pm2.js cmd=start",
16
+ "stop-pm2": "node -r ts-node/register ./src/app-pm2.ts cmd=stop",
17
+ "stop-pm2-js": "node ./target/app-pm2.js cmd=stop"
18
+ },
19
+ "dependencies": {
20
+ "@fastcar/core": "^0.3.19",
21
+ "@fastcar/koa": "^0.1.21",
22
+ "@fastcar/rpc": "^0.2.9",
23
+ "@fastcar/server": "^0.0.5",
24
+ "@fastcar/timer": "^0.2.0",
25
+ "nanoid": "3.3.4",
26
+ "ws": "^8.18.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/koa": "^2.15.0",
30
+ "@types/mocha": "^10.0.10",
31
+ "@types/node": "^22.10.1",
32
+ "@types/tz-offset": "^0.0.0",
33
+ "mocha": "^9.1.4",
34
+ "ts-node": "^10.9.2",
35
+ "tsc-alias": "^1.8.16",
36
+ "tsconfig-paths": "^4.2.0",
37
+ "typescript": "^5.9.3"
38
+ },
39
+ "peerDependencies": {
40
+ "pm2": "^6.0.14"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "pm2": {
44
+ "optional": true
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,56 @@
1
+ #应用的基础配置
2
+ settings:
3
+ hotterSysConfig: true #监听系统配置
4
+ microservices:
5
+ center: #应用类型
6
+ token: "nW0tT4bZ6qM7mF7wD2rT2pR9dT7gK3hZ"
7
+ servers:
8
+ - host: "localhost"
9
+ clusters: 1 #代表有两个这样的 serviceId和prot端口号都递增
10
+ list:
11
+ - type: "ws"
12
+ server: { port: 60000 }
13
+ timeout: 0 #设置永不超时
14
+ connectionLimit: 1
15
+ disconnectInterval: 1000 #断线重连1秒
16
+ retry: { retryCount: 3, retryInterval: 3000, timeout: 30000, maxMsgNum: 10000, increase: true }
17
+ - host: "localhost"
18
+ clusters: 3 #代表有两个这样的 serviceId和prot端口号都递增
19
+ list:
20
+ - type: "ws"
21
+ server: { port: 60000 }
22
+ timeout: 0 #设置永不超时
23
+ connectionLimit: 1
24
+ disconnectInterval: 1000 #断线重连1秒
25
+ retry: { retryCount: 3, retryInterval: 3000, timeout: 30000, maxMsgNum: 10000, increase: true }
26
+ connector:
27
+ token: "x3TGsWC9uloZu235LA07eAiJ61nQ1A5f"
28
+ servers:
29
+ - host: "localhost"
30
+ clusters: 1
31
+ list:
32
+ - front: true
33
+ type: "ws"
34
+ server: { port: 60100 }
35
+ chat:
36
+ token: "go0kbkNM3wQ4e2Vgo0kbkNM3wQ4e2V"
37
+ servers:
38
+ - host: "localhost"
39
+ clusters: 1
40
+ list:
41
+ - type: "ws"
42
+ server: { port: 60200 }
43
+ web:
44
+ token: "go0kbkNM3wQ4e2Vgo0kbkNM3wQ4e2V"
45
+ koa:
46
+ koaBodyParser: #koabody设置 新增xml解析
47
+ enableTypes: ["json", "form", "text"]
48
+ extendTypes: { text: ["text/xml", "application/xml"] }
49
+ servers:
50
+ - host: "localhost"
51
+ clusters: 1
52
+ list:
53
+ - type: "http"
54
+ server: { port: 8080 } #服务器配置 支持 http http2和https
55
+ - type: "ws"
56
+ server: { port: 60300 }
@@ -0,0 +1,2 @@
1
+ application:
2
+ env: "dev"
@@ -0,0 +1,76 @@
1
+ import "reflect-metadata";
2
+ import { ServerKind } from "@/common/Constant";
3
+ import Result from "@/common/Result";
4
+ import Code from "@/common/Code";
5
+ import { SessionAttribute } from "@/types/SessionAttribute";
6
+ import { ClassUtils } from "@fastcar/core/utils";
7
+ import { ForwardRpcContext } from "@/types/ForwardRpcContext";
8
+ import { MethodType, RpcMetaData } from "@fastcar/rpc";
9
+
10
+ const BASETYPE = ["constructor", "prototype", "name"];
11
+
12
+ //定义方法
13
+ function defineFunction(desc: PropertyDescriptor, role: ServerKind[]): PropertyDescriptor {
14
+ let beforeFN = desc.value;
15
+ desc.value = function (data: any, ctx: ForwardRpcContext) {
16
+ if (ctx.forward) {
17
+ let session = ctx.session;
18
+
19
+ if (!session) {
20
+ return Result.errorCode(Code.COMMON.PERMISSIONS_MISSING);
21
+ }
22
+
23
+ let sessionRole = session.settings.get(SessionAttribute.serverKind);
24
+
25
+ if (!role.includes(sessionRole)) {
26
+ return Result.errorCode(Code.COMMON.PERMISSIONS_MISSING);
27
+ }
28
+
29
+ return Promise.resolve(Reflect.apply(beforeFN, this, [data, ctx]));
30
+ }
31
+
32
+ //优先从session会话中判断
33
+ let roleLevel = ctx.settings.get(SessionAttribute.serverKind);
34
+ if (!role.includes(roleLevel)) {
35
+ return Result.errorCode(Code.COMMON.PERMISSIONS_MISSING);
36
+ }
37
+
38
+ return Promise.resolve(Reflect.apply(beforeFN, this, [data, ctx]));
39
+ };
40
+
41
+ return desc;
42
+ }
43
+
44
+ //校验角色
45
+ export default function AuthServiceRole(...role: ServerKind[]) {
46
+ return function (target: any, methodName?: string, descriptor?: PropertyDescriptor) {
47
+ if (methodName && descriptor) {
48
+ defineFunction(descriptor, role);
49
+ } else {
50
+ let keys = ClassUtils.getProtoType(target);
51
+ let routerMap: Map<string, MethodType> = Reflect.getMetadata(RpcMetaData.RPCMethod, target.prototype);
52
+
53
+ if (!routerMap || routerMap.size == 0) {
54
+ return;
55
+ }
56
+
57
+ let methods: string[] = [];
58
+ routerMap.forEach((v) => {
59
+ methods.push(v.method);
60
+ });
61
+
62
+ keys.forEach((item) => {
63
+ if (BASETYPE.includes(item.toString())) {
64
+ return;
65
+ }
66
+ if (!methods.includes(item.toString())) {
67
+ return;
68
+ }
69
+ let desc: PropertyDescriptor | undefined = Reflect.getOwnPropertyDescriptor(target.prototype, item);
70
+ if (desc) {
71
+ Reflect.defineProperty(target.prototype, item, defineFunction(desc, role));
72
+ }
73
+ });
74
+ }
75
+ };
76
+ }
@@ -0,0 +1,13 @@
1
+ import { setHotKey } from "@/hotconfig/HotConfigInterface";
2
+ import { ComponentInjection } from "@fastcar/core/annotation";
3
+ import path = require("path");
4
+
5
+ export default function EnableHotConfig(obj: { [rp: string]: string[] }) {
6
+ return function (target: any) {
7
+ Object.keys(obj).forEach((rp) => {
8
+ let fp = require.resolve(path.join(__dirname, "../", "hotconfig", rp));
9
+ setHotKey(fp, Reflect.get(obj, rp));
10
+ ComponentInjection(target, fp);
11
+ });
12
+ };
13
+ }
@@ -0,0 +1,94 @@
1
+ import { ChildProcess, spawn, SpawnOptions } from "child_process";
2
+ import { FileUtil } from "@fastcar/core/utils";
3
+ import * as path from "path";
4
+ import { execPath } from "process";
5
+ import NetWork from "./utils/NetWork";
6
+ import * as fs from "fs";
7
+ import MicroservicesUtils from "./utils/MicroservicesUtils";
8
+
9
+ //使用子进程启动微服务
10
+ class APPNode {
11
+ spawnProcess(options: string[], debug: boolean = false) {
12
+ let stdioArgs: SpawnOptions = { detached: true, stdio: "inherit" };
13
+ let child: ChildProcess = spawn(execPath, options, debug ? {} : stdioArgs);
14
+
15
+ child?.stderr?.on("data", function (chunk) {
16
+ process.stderr.write(chunk.toString());
17
+ });
18
+
19
+ child?.stdout?.on("data", function (chunk) {
20
+ process.stdout.write(chunk.toString());
21
+ });
22
+
23
+ child.on("error", function (error) {
24
+ console.error(error);
25
+ });
26
+
27
+ child.on("exit", function (code) {
28
+ if (code !== 0) {
29
+ console.error("child process exit with error, error code: %s", code);
30
+ }
31
+ });
32
+ }
33
+
34
+ start() {
35
+ const serverPath = path.join(__dirname, "servers");
36
+ //加载配置
37
+ //根据配置读取server集群
38
+ let microservices = MicroservicesUtils.getMicroservicesConfig();
39
+ microservices = MicroservicesUtils.format(microservices);
40
+
41
+ let pargs = MicroservicesUtils.parseArgs(process.argv);
42
+ let argServerType = Reflect.get(pargs, "serverType");
43
+ let argServiceId = Reflect.get(pargs, "serviceId");
44
+
45
+ Object.keys(microservices).forEach((serverType) => {
46
+ if (argServerType && argServerType != serverType) {
47
+ return;
48
+ }
49
+
50
+ //判断是否为本地IP
51
+ let item = microservices[serverType];
52
+ let servers = item.servers;
53
+ servers.forEach((s) => {
54
+ if (argServiceId && argServiceId != s.serviceId) {
55
+ return;
56
+ }
57
+
58
+ if (NetWork.isLocalIP(s.host)) {
59
+ try {
60
+ let args: string[] = [];
61
+
62
+ if (!!s.debugPort) {
63
+ args.push(`--inspect=${s.host}:${s.debugPort}`);
64
+ }
65
+
66
+ let scriptPath = require.resolve(path.join(serverPath, serverType, "app"));
67
+ if (!fs.existsSync(scriptPath)) {
68
+ return;
69
+ }
70
+ if (FileUtil.getSuffix(scriptPath) == "ts") {
71
+ args.push("-r");
72
+ args.push("ts-node/register");
73
+ }
74
+
75
+ args.push(scriptPath);
76
+
77
+ args.push(serverType);
78
+ args.push(s.serviceId);
79
+
80
+ this.spawnProcess(args, !!s.debugPort);
81
+ } catch (e) {
82
+ console.error(`${s.serviceId} startup failed`);
83
+ console.error(e);
84
+ }
85
+ }
86
+ });
87
+ });
88
+ }
89
+ }
90
+
91
+ //设置时区
92
+ process.env.TZ = "UTC";
93
+
94
+ export default new APPNode().start();