执行长时间任务(46及以后的版本)
场景描述
如果一个服务需要执行比较长的时间,没有任何返回,超过设置的超时时间后,前端就会收到504,在某些网络环境下,还会造成网络重试。
从46版本开始,系统支持在调用长时间服务时,实时返回执行进度,不造成超时,且界面上可以显示进度条。
实现思路
启用响应流模式,利用 ProgressiveTaskUtil 实时通知客户端处理进度,保持响应流的连续。
实现步骤
- 定义服务时,选中“启用响应流模式”
在服务中
- 首先调用 ProgressiveTaskUtil.getCurrentTask 方法获取当前任务
- 然后根据业务处理情况,择机调用当前任务的setPercent方法,设置后,前端即可收到设置的百分比
- 最后正常返回数据
java代码如下:
public String longTimeService() throws Exception {
ProgressiveTask<String> task = ProgressiveTaskUtil.getCurrentTask();
for(int i=0;i<=100;i++) {
Thread.sleep(100);
JSONObject extInfo = new JSONObject();
task.setPercent(i, "进度", extInfo);//后两个参数不能为空
}
Thread.sleep(100);
return "OK";
}
涉及到的引用如下
import com.alibaba.fastjson.JSONObject;
import com.justep.util.progressive.ProgressiveTaskUtil;
import com.justep.util.progressive.ProgressiveTaskUtil.ProgressiveTask;
前端页面调用服务,在响应进度消息事件中,获取百分比
使用服务请求组件
//在响应进度消息事件中,获取百分比 onServiceRequest0Message = (event) => { this.comp("pageData").setValue("percent",event.message.percent); } //在请求成功事件中,获取返回数据 onServiceRequest0Success = (event) => { message.info(event.data); }
使用 this.request
onButton1Click = async (event) => { let {data} = await this.request({ url:"$serviceName/main/fuwu/longtimeservice" }) //在响应进度消息事件中,获取百分比 data.on("message",(message)=>{ this.comp("pageData").setValue("percent",message.percent); }) //在请求成功事件中,获取返回数据 data.on("done",(data)=>{ message.info(data); }) }
运行效果如下图所示
可以看到响应头中的 Content-Type 是 text/event-stream;charset=UTF-8
执行长时间任务(45及以前的版本)
场景描述
如果一个服务需要执行比较长的时间,没有任何返回,超过设置的超时时间后,前端就会收到504,在某些网络环境下,还会造成网络重试。
从46版本开始,系统支持在调用长时间服务时,返回执行进度,用于界面上显示进度条。
实现思路
在服务执行中不断返回response,前端就会认为服务正在执行,不会出现504
实现步骤
在java代码中,根据业务处理情况,择机返回response。本例使用循环,每1000条数据返回一次response,代码如下:
//获取response
HttpServletResponse response = SpringWebUtil.getResponse();
//使用分块传输
response.setHeader("Transfer-Encoding","chunked");
//在业务处理中,择机返回response
for (int i=0;i< users.size();i++) {
//每1000条数据,返回一下,避免出现504
if(i % 1000 == 0) {
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write((i+"\n").getBytes());
outputStream.flush();
}
}
涉及到的引用如下
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import com.justep.util.SpringWebUtil;
运行效果如下图所示