Files
contract-manager/docs/task/client_server_tasker_communication_rules.md
songqq 2057c3ca67 feat: 实现客户端与服务器端Tasker通信机制及文件管理功能
refactor: 重构Tasker基类与服务获取逻辑
fix: 修复文件路径显示问题及任务注册加载机制
docs: 添加客户端与服务器端Tasker通信规则文档
style: 优化代码格式与日志输出
build: 添加tasker_mapper.json配置文件
chore: 清理无用代码与文件
2025-09-25 00:14:34 +08:00

8.5 KiB
Raw Blame History

客户端 Tasker 至 服务器端 Tasker 通信规则与逻辑

本文档总结了 Contract-Manager 项目中客户端 Tasker 与服务器端 Tasker 之间的通信规则、调用逻辑和实现模式,基于对以下文件的分析:

  • d:\idea-workspace\Contract-Manager\server\src\main\java\com\ecep\contract\ds\customer\tasker\CompanyCustomerEvaluationFormUpdateTask.java
  • d:\idea-workspace\Contract-Manager\client\src\main\java\com\ecep\contract\controller\customer\CompanyCustomerEvaluationFormUpdateTask.java
  • d:\idea-workspace\Contract-Manager\client\src\main\java\com\ecep\contract\controller\customer\CustomerTabSkinFile.java

1. 架构设计原则

项目采用了清晰的客户端-服务器分离架构,任务处理遵循以下原则:

  • 客户端轻量级:负责任务发起、参数传递和结果展示
  • 服务器端重量级:负责实际业务逻辑处理和数据操作
  • WebSocket通信使用WebSocket实现客户端与服务器端的任务通信和进度同步

2. 类命名与结构规范

2.1 命名规则

  • 客户端与服务器端的对应Tasker类必须使用相同的类名(如示例中的CompanyCustomerEvaluationFormUpdateTask
  • 客户端Tasker位于client模块的控制器包下
  • 服务器端Tasker位于server模块的tasker包下

2.2 任务名称注册规则

  • 所有服务器端Tasker类必须通过配置文件tasker_mapper.json进行注册,并由WebSocketServerTaskManager类在afterPropertiesSet方法中加载
  • 注册格式为"TaskClassName": "fully.qualified.ClassName"
  • 注册的Task名称将用于客户端和服务器端之间的任务识别
  • 配置文件tasker_mapper.json应位于src/main/resources目录下,格式如下:
{
    "taskers": {
        "TaskClassName": "fully.qualified.ClassName",
        // 更多任务映射...
    }
}

任务名称注册实现示例

@Override
public void afterPropertiesSet() throws Exception {
    // 从tasker_mapper.json文件中加载任务注册信息
    try {
        Resource resource = resourceLoader.getResource("classpath:tasker_mapper.json");
        try (InputStream inputStream = resource.getInputStream()) {
            JsonNode rootNode = objectMapper.readTree(inputStream);
            JsonNode taskersNode = rootNode.get("taskers");
            if (taskersNode != null && taskersNode.isObject()) {
                Map<String, String> taskMap = new java.util.HashMap<>();
                taskersNode.fields().forEachRemaining(entry -> {
                    taskMap.put(entry.getKey(), entry.getValue().asText());
                });
                taskClzMap = taskMap;
            }
        }
    } catch (Exception e) {
        logger.error("Failed to load tasker_mapper.json", e);
        // 使用默认值作为fallback
        taskClzMap = Map.of();
    }
}```

### 2.3 接口实现区分
- 客户端Tasker实现`WebSocketClientTasker`接口
- 服务器端Tasker实现`WebSocketServerTasker`接口

### 2.4 继承关系
- 客户端和服务器端Tasker均继承自`Tasker<Object>`基类

## 3. 客户端Tasker实现规则

客户端Tasker是任务的发起方需要遵循以下实现规则

### 3.1 核心属性
- 通常包含一个可设置的业务对象如示例中的`@Setter private CompanyCustomerVo customer;`
- 配置Logger日志记录器

### 3.2 核心方法实现
- **getTaskName()**返回任务名称通常使用类名
- **updateProgress()**继承或重写进度更新方法
- **execute()**调用`callRemoteTask()`方法将任务发送到服务器端传递必要参数

### 3.3 示例实现
```java
public class CompanyCustomerEvaluationFormUpdateTask extends Tasker<Object> implements WebSocketClientTasker {
    private static final Logger logger = LoggerFactory.getLogger(CompanyCustomerEvaluationFormUpdateTask.class);

    @Setter
    private CompanyCustomerVo customer;  // 业务对象

    @Override
    public String getTaskName() {
        return getClass().getSimpleName();
    }

    @Override
    protected Object execute(MessageHolder holder) throws Exception {
        updateTitle("客户评估表更新任务");  // 设置任务标题
        // 调用远程任务传递locale和业务对象ID
        return callRemoteTask(holder, getLocale(), customer.getId());
    }
}

4. 服务器端Tasker实现规则

服务器端Tasker是任务的实际执行者需要遵循以下实现规则

4.1 参数接收

  • 实现init(JsonNode argsNode)方法接收客户端传递的参数
  • 从参数中提取业务对象ID并加载完整业务对象

4.2 服务获取

  • 通过getCachedBean(Service.class)方法获取所需的服务实例
  • 可以提供辅助方法封装服务获取逻辑

4.3 任务执行

  • 实现execute(MessageHolder holder)方法包含实际业务逻辑
  • 使用holder.info()/error()等方法记录任务执行状态
  • 调用updateProgress()方法更新任务进度

4.4 示例实现

public class CompanyCustomerEvaluationFormUpdateTask extends Tasker<Object> implements WebSocketServerTasker {
    private CompanyCustomer customer;  // 业务对象

    @Override
    public void init(JsonNode argsNode) {
        // 从参数中提取业务对象ID并加载
        int customerId = argsNode.get(0).asInt();
        customer = getCachedBean(CompanyCustomerService.class).findById(customerId);
    }

    // 辅助方法获取服务
    CompanyCustomerFileService getCompanyCustomerFileService() {
        return getCachedBean(CompanyCustomerFileService.class);
    }

    @Override
    protected Object execute(MessageHolder holder) throws Exception {
        // 执行实际业务逻辑
        updateEvaluationForm(holder);
        return null;
    }

    // 具体业务逻辑实现
    public void updateEvaluationForm(MessageHolder holder) {
        // 业务逻辑代码...
        updateProgress(1, 10);  // 更新进度
        // 更多业务逻辑...
    }
}

5. 客户端Tasker调用流程

在UI控制器中调用客户端Tasker的标准流程如下

5.1 实例化与参数设置

  1. 创建客户端Tasker实例
  2. 设置必要的业务对象参数

5.2 任务执行与监控

  1. 使用UITools.showTaskDialogAndWait()显示任务对话框
  2. 调用initializeTask()初始化任务执行环境
  3. 通过消费者函数处理任务消息

5.3 任务完成处理

  1. 任务完成后执行必要的数据刷新操作

5.4 示例调用

public void onUpdateEvaluationFormAction(ActionEvent event) {
    // 1. 创建Tasker并设置参数
    CompanyCustomerEvaluationFormUpdateTask task = new CompanyCustomerEvaluationFormUpdateTask();
    task.setCustomer(getCompanyCustomerService().findById(viewModel.getId().get()));
    
    // 2. 显示任务对话框并执行任务
    UITools.showTaskDialogAndWait("更新评价表", task, consumer -> {
        initializeTask(task, "更新评价表", msg -> consumer.accept(Message.info(msg)));
    });
    
    // 3. 任务完成后刷新数据
    loadTableDataSet();
}

6. 任务进度管理

  • 服务器端使用updateProgress(current, total)方法更新任务进度
  • 进度值通常以0-1000或类似小范围数值表示完成百分比
  • 客户端通过WebSocket接收进度更新并显示

7. 异常处理机制

  • 服务器端使用MessageHolder.error()方法记录错误信息
  • 客户端通过任务对话框展示错误信息
  • 服务器端在关键操作点进行异常捕获和处理

8. 数据一致性保障

  • 任务完成后客户端通常调用数据刷新方法(如loadTableDataSet()确保UI显示最新数据
  • 服务器端负责业务数据的持久化操作

9. 最佳实践建议

  1. 任务拆分:复杂任务应拆分为多个小任务,便于进度跟踪和错误定位
  2. 状态反馈:在关键节点提供清晰的状态信息,增强用户体验
  3. 资源释放:确保文件流等资源正确关闭,避免资源泄露
  4. 事务控制:对于涉及多步数据操作的任务,考虑使用事务确保数据一致性
  5. 错误重试:针对网络波动等临时性问题,考虑实现任务重试机制
  6. 配置管理:使用tasker_mapper.json文件统一管理任务注册信息,避免在代码中硬编码任务映射
  7. 异常处理确保实现配置文件加载失败的fallback机制保证系统稳定性
  8. 版本控制:对任务配置文件进行版本控制,便于追踪变更历史

通过遵循以上规则和模式可以确保Contract-Manager项目中客户端与服务器端Tasker通信的一致性、可靠性和可维护性。