# XFrameCore **Repository Path**: osby/XFrameCore ## Basic Information - **Project Name**: XFrameCore - **Description**: xFrame核心程序 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2020-07-25 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 项目名称 XFrameCore # API 1. `XFrameCore`核心模块 - 模块启动 ``` java -jar [module.jarInfo.path] -- 上传的.jar绝对路径 --server.port=[module.webPort] -- Web服务端口 -Dfile.encoding=UTF-8 -- Java程序文件编码 --mid=[module.id] -- Module ID --token=[token] -- 本次服务token, token仅用于XFrame内部通信校验 ``` - 模块停止 ``` "http://localhost:[module.webPort]/shutdown" - module.webPort: web服务端口 ``` 【注意】: 如果调用`/shutdown/{id}/{token}`失败, `XFrameCore`将会采取杀死进程的方式强制停止模块, 届时可能会造成资源回收不及时的问题. - 修改模块日志目录, 文件名默认[`spring.log`]即可 ``` "/logDir/{id}/{token}/{logDir}" -id: 模块ID, 模块启动时通过参数[mid]获取 -token: 启动令牌, 模块启动时通过参数[token]获取 -logDir: 日志文件目录使用base64编码(UTF-8) ``` 2. `XFrameModule`模块 启动成功时应该立即将日志文件目录告知`XFrameCore` ``` String logDir = StringUtil.base64Enc(logFileDir); // 请求地址 "http://localhost/module/logDir/{id}/{token}/{logDir}" -logFileDir: 日志文件目录, 自定义 -id: 模块ID, 模块启动时通过参数[mid]获取 -token: 启动令牌, 模块启动时通过参数[token]获取 -logDir: logFileDir的base64编码(UTF-8) ``` - 模块停止API ``` "/shutdown/{mid}/{token}" - mid: 启动模块时分配的ID - token: 本次服务token ``` 模块停止时必须执行 `mid`&`token`双重校验 - 获取日志目录, 文件名默认[`spring.log`]即可 ``` "/logDir/{mid}/{token}" - mid: 启动模块时分配的ID - token: 本次服务token ``` 必须执行 `mid`&`token`双重校验 3. `XFrameService`服务模块 4. `XFrameApplication`应用模块 - 应用入口 ``` "/index/{mid}/{token}" - mid: 启动模块时分配的ID - token: 本次服务token ``` 必须执行 `mid`&`token`双重校验 - 应用与Desktop在前端交互 - 发送消息 ```js let data = 'WIN_EXIT'; // 退出程序 top.postMessage(JSON.stringify(data), '*'); ``` - 用户登录授权 # 知识要点 1. 通过`Runtime`执行命令需要加上前缀, 示例代码为查询指定端口占用情况 ```java // windows String[] commands = { // 系统指令前缀 "cmd", "/c", // 具体指令 "netstat", "-aon", "|findstr", String.valueOf(port) }; Process prc = rt.exec(commands); // linux String[] commands = { // 系统指令前缀 "/bin/sh", "-c", // 具体指令 "netstat", "-ntulp", "|grep ", String.valueOf(port) }; Process prc = rt.exec(commands); ``` 在`JVM`环境中启动`SpringBoot.jar`程序没有执行到Springboot`事件`, 转由`.bat`文件执行 ```shell script @echo off start javaw -jar D:\xframe\upload\jar\45E20CBFE4054892A4821DB1A823208E.jar --server.port=9000 -Dfile.encoding=UTF-8 --server.servlet.session.cookie.name=F920476681CE4E97B2988A13AD2C1B7C --mid=2 --token=290E1F1C3D1C49A09D7F058296A65E70 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 @echo on exit ``` 2. `RandomAccessFile`读取文件会存在编码问题, 需要手动转码 ```java RandomAccessFile ra = new RandomAccessFile("test.txt", "rw"); ra.seek(0); ra.write("Chinese 中文".getBytes()); ra.seek(0); // 需要重新转码才能正常显示 System.out.println(new String(ra.readLine().getBytes("ISO-8859-1"),"utf-8")); ra.close(); ``` 3. angular中`iframe.src`的值需要`SafeResourceUrl` ``` // 导入 import { DomSanitizer } from '@angular/platform-browser'; // 注入 constructor(private sanitizer: DomSanitizer) {} // 转化为安全地址 this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url); // 引用 ``` 4. angular中`iframe`加载页面导致主页面阻塞 - 解决方案1: `iframe.src`指向`xframe`的中转静态页面`/public/post.html`, 并通过`?uri=index/{id}/{token}&port={webPort}`将`应用模块`首页地址传递到`post.html`页面中, `post.html`页面通过`location.href=url`直接跳转到目标页面. `post.html`页面应该尽量的小: ```html ``` 测试发现, 如果`iframe.src`指向`xx.html`会把当前页面的`jsessionid`改变, 导致当前用户被迫下线, 通过配置sessionCookieName解决: ```yaml # 在Module添加启动参数 server.servlet.session.cookie.name: notepadSessionID ``` 5. `nz-upload`图片回填 - 从列表页面直接把图片地址传递到编辑页面进行回显: `OK` - 通过ID从后台获取图片地址回显: `FAIL`, 原因未知. # 任务计划 - [x] 用户注册登录