generated from tailored/router-template
	add check port and change process
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -13,3 +13,5 @@ cache-file | |||||||
|  |  | ||||||
| logs | logs | ||||||
| root/ | root/ | ||||||
|  |  | ||||||
|  | release/*.tgz | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "@kevisual/assistant-module", |   "name": "@kevisual/assistant-module", | ||||||
|   "version": "0.0.3", |   "version": "0.0.4-beta.2", | ||||||
|   "description": "assistant module", |   "description": "assistant module", | ||||||
|   "main": "dist/assistant-module.mjs", |   "main": "dist/assistant-module.mjs", | ||||||
|   "types": "dist/assistant-module.d.ts", |   "types": "dist/assistant-module.d.ts", | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								assistant-module/src/https/create-sign.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								assistant-module/src/https/create-sign.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | import { createCert } from '@kevisual/router/sign'; | ||||||
|  | import { writeFileSync } from 'fs'; | ||||||
|  | import path from 'path'; | ||||||
|  | const pemDir = path.join(process.cwd(), 'router-app', 'pem'); | ||||||
|  |  | ||||||
|  | const { key, cert } = createCert([ | ||||||
|  |   { | ||||||
|  |     name: 'commonName', | ||||||
|  |     value: 'localhost', | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     name: 'organizationName', | ||||||
|  |     value: 'kevisual', | ||||||
|  |   }, | ||||||
|  | ]); | ||||||
|  |  | ||||||
|  | writeFileSync(path.join(pemDir, 'https-key.pem'), key); | ||||||
|  | writeFileSync(path.join(pemDir, 'https-cert.pem'), cert); | ||||||
| @@ -1,32 +1,40 @@ | |||||||
| import { ChildProcess, fork } from 'child_process'; | import { ChildProcess, fork, ForkOptions } from 'child_process'; | ||||||
|  |  | ||||||
| export const runProcess = (appPath: string) => { |  | ||||||
|   const process = fork(appPath); |  | ||||||
|   process.on('exit', (code) => { |  | ||||||
|     console.log(`Process exited with code ${code}`); |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
|   process.on('message', (message) => { |  | ||||||
|     console.log('Message from child:', message); |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
|   // Example of sending a message to the child process |  | ||||||
|   // process.send({ hello: 'world' }); |  | ||||||
| }; |  | ||||||
| class BaseProcess { | class BaseProcess { | ||||||
|   private process: ChildProcess; |   private process: ChildProcess; | ||||||
|   status: 'running' | 'stopped' | 'error' = 'stopped'; |   status: 'running' | 'stopped' | 'error' = 'stopped'; | ||||||
|   appPath: string; |   appPath: string; | ||||||
|   constructor(appPath: string) { |   args: any[] = []; | ||||||
|  |   opts: ForkOptions = {}; | ||||||
|  |   /* | ||||||
|  |    * 重启次数, 默认0, TODO, 错误检测,当重启次数超过一定次数,则认为进程已崩溃 | ||||||
|  |    */ | ||||||
|  |   restartCount: number = 0; | ||||||
|  |   constructor(appPath?: string, args?: any[], opts?: ForkOptions) { | ||||||
|     this.appPath = appPath; |     this.appPath = appPath; | ||||||
|  |     this.args = args || []; | ||||||
|  |     this.opts = opts || {}; | ||||||
|     // this.createProcess(appPath); |     // this.createProcess(appPath); | ||||||
|   } |   } | ||||||
|   createProcess(appPath: string = this.appPath) { |   createProcess(appPath: string = this.appPath, args: any[] = [], opts: ForkOptions = {}) { | ||||||
|     if (this.process) { |     if (this.process) { | ||||||
|       this.process.kill(); |       this.process.kill(); | ||||||
|     } |     } | ||||||
|     this.appPath = appPath; |     this.appPath = appPath || this.appPath; | ||||||
|     this.process = fork(appPath); |     this.args = args || this.args; | ||||||
|  |     this.opts = { | ||||||
|  |       ...this.opts, | ||||||
|  |       ...opts, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     this.process = fork(appPath, args, { | ||||||
|  |       stdio: 'inherit', | ||||||
|  |       ...this.opts, | ||||||
|  |       env: { | ||||||
|  |         ...process.env, | ||||||
|  |         NODE_ENV_PARENT: 'fork', | ||||||
|  |         ...this.opts?.env, | ||||||
|  |       }, | ||||||
|  |     }); | ||||||
|     return this; |     return this; | ||||||
|   } |   } | ||||||
|   kill(signal?: NodeJS.Signals | number) { |   kill(signal?: NodeJS.Signals | number) { | ||||||
| @@ -62,6 +70,10 @@ class BaseProcess { | |||||||
|   public onDisconnect(callback: () => void) { |   public onDisconnect(callback: () => void) { | ||||||
|     this.process.on('disconnect', callback); |     this.process.on('disconnect', callback); | ||||||
|   } |   } | ||||||
|  |   restart() { | ||||||
|  |     this.kill(); | ||||||
|  |     this.createProcess(); | ||||||
|  |   } | ||||||
| } | } | ||||||
| export class AssistantProcess extends BaseProcess { | export class AssistantProcess extends BaseProcess { | ||||||
|   constructor(appPath: string) { |   constructor(appPath: string) { | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ export const defaultApiProxy = [ | |||||||
|  * @param paths ['/api/router', '/v1' ] |  * @param paths ['/api/router', '/v1' ] | ||||||
|  * @returns |  * @returns | ||||||
|  */ |  */ | ||||||
| export const createApiProxy = (api: string, paths: string[] = ['/api/router', '/v1']) => { | export const createApiProxy = (api: string, paths: string[] = ['/api/router', '/v1', '/resources']) => { | ||||||
|   const pathList = paths.map((item) => { |   const pathList = paths.map((item) => { | ||||||
|     return { |     return { | ||||||
|       path: item, |       path: item, | ||||||
|   | |||||||
| @@ -9,7 +9,8 @@ | |||||||
|     "type": "system-app", |     "type": "system-app", | ||||||
|     "files": [ |     "files": [ | ||||||
|       "dist", |       "dist", | ||||||
|       "pem" |       "pem", | ||||||
|  |       "root" | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
| @@ -28,9 +29,9 @@ | |||||||
|   "type": "module", |   "type": "module", | ||||||
|   "types": "types/index.d.ts", |   "types": "types/index.d.ts", | ||||||
|   "files": [ |   "files": [ | ||||||
|     "types", |  | ||||||
|     "dist", |     "dist", | ||||||
|     "src" |     "pem", | ||||||
|  |     "root" | ||||||
|   ], |   ], | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@kevisual/code-center-module": "0.0.13", |     "@kevisual/code-center-module": "0.0.13", | ||||||
| @@ -39,6 +40,7 @@ | |||||||
|     "cookie": "^1.0.2", |     "cookie": "^1.0.2", | ||||||
|     "dayjs": "^1.11.13", |     "dayjs": "^1.11.13", | ||||||
|     "formidable": "^3.5.2", |     "formidable": "^3.5.2", | ||||||
|  |     "get-port": "^7.1.0", | ||||||
|     "json5": "^2.2.3", |     "json5": "^2.2.3", | ||||||
|     "lodash-es": "^4.17.21", |     "lodash-es": "^4.17.21", | ||||||
|     "ws": "^8.18.1" |     "ws": "^8.18.1" | ||||||
|   | |||||||
							
								
								
									
										365
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										365
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								release/release.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								release/release.mjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | console.log('release'); | ||||||
| @@ -8,7 +8,7 @@ import replace from '@rollup/plugin-replace'; | |||||||
| import pkgs from './package.json' with {type: 'json'}; | import pkgs from './package.json' with {type: 'json'}; | ||||||
|  |  | ||||||
| const isDev = process.env.NODE_ENV === 'development'; | const isDev = process.env.NODE_ENV === 'development'; | ||||||
| const input = isDev ? './src/dev.ts' : './src/index.ts'; | const input = isDev ? './src/dev.ts' : './src/main.ts'; | ||||||
| /** | /** | ||||||
|  * @type {import('rollup').RollupOptions} |  * @type {import('rollup').RollupOptions} | ||||||
|  */ |  */ | ||||||
| @@ -64,8 +64,8 @@ const config = { | |||||||
|     json(), |     json(), | ||||||
|   ], |   ], | ||||||
|   external: [ |   external: [ | ||||||
|     /@kevisual\/router(\/.*)?/, //, // 路由 |     // /@kevisual\/router(\/.*)?/, //, // 路由 | ||||||
|     /@kevisual\/use-config(\/.*)?/, // |     // /@kevisual\/use-config(\/.*)?/, // | ||||||
|  |  | ||||||
|     // 'sequelize', // 数据库 orm |     // 'sequelize', // 数据库 orm | ||||||
|     // 'ioredis', // redis |     // 'ioredis', // redis | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ app | |||||||
|   .addTo(app); |   .addTo(app); | ||||||
|  |  | ||||||
| console.log('httpsConfig', `https://localhost:51015/client/router?path=demo`); | console.log('httpsConfig', `https://localhost:51015/client/router?path=demo`); | ||||||
| app.listen(51015, () => { | app.listen(51016, () => { | ||||||
|   console.log('Router App is running on https://localhost:51015'); |   console.log('Router App is running on https://localhost:51015'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								src/main.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/main.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | import { app } from './index.ts'; | ||||||
|  | import { proxyRoute } from './proxy-route/index.ts'; | ||||||
|  | import getPort, { portNumbers } from 'get-port'; | ||||||
|  | console.log('httpsConfig', `https://localhost:51015/client/router?path=demo`); | ||||||
|  | // 检车端口可用性 | ||||||
|  | const isPortAvailable = await getPort({ port: portNumbers(51015, 52000) }); | ||||||
|  | if (!isPortAvailable) { | ||||||
|  |   console.log(`Port ${isPortAvailable} is not available`); | ||||||
|  |   process.exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | app.listen(isPortAvailable, () => { | ||||||
|  |   console.log('Router App is running on https://localhost:51015'); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | app.server.on(proxyRoute); | ||||||
|  |  | ||||||
|  | // 如果是被fork启动的,向父进程发送消息 | ||||||
|  | if (process.env.NODE_ENV_PARENT === 'fork') { | ||||||
|  |   process.send({ | ||||||
|  |     type: 'fork', | ||||||
|  |     data: { | ||||||
|  |       port: isPortAvailable, | ||||||
|  |     }, | ||||||
|  |   }); | ||||||
|  | } | ||||||
| @@ -118,7 +118,20 @@ export const installApp = async (app: Package) => { | |||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  | export const addCacheAssistantConfig = (config: any) => { | ||||||
|  |   const cacheAssistantConfig = getCacheAssistantConfig(); | ||||||
|  |   let proxy = cacheAssistantConfig.proxy || []; | ||||||
|  |   const index = proxy.findIndex((item: any) => item.user === config.user && item.key === config.key); | ||||||
|  |   if (index !== -1) { | ||||||
|  |     proxy[index] = config; | ||||||
|  |   } else { | ||||||
|  |     proxy.push(config); | ||||||
|  |   } | ||||||
|  |   setConfig({ | ||||||
|  |     ...cacheAssistantConfig, | ||||||
|  |     proxy, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
| export const uninstallApp = async (app: Package) => { | export const uninstallApp = async (app: Package) => { | ||||||
|   try { |   try { | ||||||
|     const { user, key } = app; |     const { user, key } = app; | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								src/scripts/port-get.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/scripts/port-get.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | import getPort from 'get-port'; | ||||||
|  |  | ||||||
|  | const port = 51015; | ||||||
|  | const isPortAvailable = await getPort({ port: [51015, 51030] }); | ||||||
|  | if (!isPortAvailable) { | ||||||
|  |   console.log(`Port ${port} is not available`); | ||||||
|  |   process.exit(1); | ||||||
|  | } | ||||||
|  | console.log(`Port ${isPortAvailable} is available`); | ||||||
|  | process.exit(0); | ||||||
		Reference in New Issue
	
	Block a user