您现在的位置是:首页 > 正文

进度条实现与后端进行交互,实时更新进度条(JAVA web项目实现) 热门推荐

2024-04-01 02:00:51阅读 2

实现思路

网页进度条更新有两种方式

1、轮询请求服务端、返回进度

2、服务端实时推送进度数据给客户端

        轮询方式的实现方法,服务端在执行的过程中将进度数据保存再session中,客户端调用的时候从session中取出来,然后更新进度条的数据,从而改变进度条。

        服务端实时推送,客户端请求执行任务的时候连接到websocket,服务端在执行的过程中将进度数据通过websocket的方式实时推送到客户端,客户端拿到数据后改变进度条

轮询请求方式

后端实现代码

    /**
	 * 任务执行方法(在实际应用中要改成自己的逻辑代码)
	*Title: execute
	*author:liuxuli
	*Description: 
	  * @param request
	  * @return
	 */
	@RequestMapping(value = "execute")
	public String execute(HttpServletRequest request) {
		
		for (int i = 0; i <= 100; i++) {
			//for循环只是个例子,在实际业务中百分比要进行实际的计算,这里的i就当是百分比
			//将进度值存储到session中
			request.getSession().setAttribute("processvalue", i);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		return "success";
	}
	/**
	 * 获取session中的进度值
	*Title: getprocess
	*author:liuxuli
	*Description: 
	  * @param request
	  * @return
	 */
	@RequestMapping(value = "getprocess")
	public Object getprocess(HttpServletRequest request) {
		//从session将执行进度值取出来并返回给用户
		return request.getSession().getAttribute("processvalue");
	}

网页端使用layui的进度条进行实现

<div class="layui-form-item">
	  	<div class="layui-input-block">
		  <div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="executeprogress" style="width: 80%;">
		  	<div id="percentdiv" class="layui-progress-bar layui-bg-green" lay-percent="0%"></div>
		  </div>
	  	</div>
	  </div>
<div class="layui-form-item">
	    <div class="layui-input-block">
	      <button class="layui-btn" lay-submit="" id="submitbtn" lay-filter="demo1">执行</button>
	    </div>
	  </div>
 
        var element;
	  	layui.use('element', function(){
		  element = layui.element;
		});
        //定义定时器
        var timer;
        //开始执行任务
        $('#submitbtn').click(function(){
	  		//进度条设置为百分之0
	  		element.progress('executeprogress', '0%');
            //轮询获取进度条数据
            getProcessvalue();
	  		//请求后台
	  		$.post('${pageContext.request.contextPath }/excute',function(data){
                //执行完成进度条设置为百分之百
	  			element.progress('executeprogress', '100%');
                //关闭定时器
                clearInterval(timer);
			});
	  	});
        //轮询请求进度数据
	  	function getProcessvalue(){
	  		//1秒请求一次进度条的数据
	  		timer = setInterval(function () {
	  			$.post('${pageContext.request.contextPath }/getprocess',function(data){
	  				//更新进度条
	  				element.progress('executeprogress', data+'%');
				});
	  		}, 1000);
	  	}

 

实时推送方式

1、创建websocket

/**
 * 创建websocketsession类,SessionConfigurator是降httpsession放入到websocket的用户属性中,
 * 如果使用springwebsocket就不需要这些配置了,因为spring的websocket框架已经配置好了
  * Title: TestWebsocket
  * Description: 
  * @author liuxuli
  * @date 2020年6月29日
 */
@ServerEndpoint(value = "/testwebsocket",configurator = SessionConfigurator.class)
public class TestWebsocket {

	/**
	 * 存储所有在线的用户(观察者模式)
	 */
	private static Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();
	/**
	 * 当用户连接到websocket,将该用户进行记录
	*Title: onopen
	*author:liuxuli
	*Description: 
	  * @param session
	  * @param config
	 */
	@OnOpen
	public void onopen(Session session,EndpointConfig config) {
		HttpSession httpsession = (HttpSession) session.getUserProperties().get(HttpSession.class.getName());
		System.out.println("连接成功");
		sessions.put(httpsession.getId(), session);
	}
	/**
	 * 当用户退出连接后,将该用户进行删除
	*Title: onClose
	*author:liuxuli
	*Description: 
	  * @param session
	 */
	@OnClose
	public void onClose(Session session) {
		HttpSession httpsession = (HttpSession) session.getUserProperties().get(HttpSession.class.getName());
		System.out.println("连接关闭");
		sessions.remove(httpsession.getId());
	}
	@OnError
	public void OnError(Throwable error,Session session) {
		System.out.println("错误");
		error.printStackTrace();
	}
	/**
	 * 向指定的用户发送消息
	*Title: sendMessage
	*author:liuxuli
	*Description: 
	  * @param httpsession 必须使用这个参数,如果不使用此参数来区分接收的用户,既浪费服务器资源,还能使所有的用户都能收到消息
	  * @param text	发送的消息
	 */
	public static void sendMessage(HttpSession httpsession,String text) {
		Session session = sessions.get(httpsession.getId());
		if (text != null && text.length() > 0) {
			session.getAsyncRemote().sendText(text);
		}
		
	}
}

SessionConfigurator类代码:

/**
 * 用来获取客户端的sessionid 从而绑定到websocket
  * Title: SessionConfigurator
  * Description: 
  * @author liuxuli
  * @date 2020年6月29日
 */
public class SessionConfigurator extends Configurator{

	@Override
	public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
		//获取到客户端的session
		HttpSession session = (HttpSession) request.getHttpSession();
		//将session当如到websocket的用户属性中
		sec.getUserProperties().put(HttpSession.class.getName(), session);
		super.modifyHandshake(sec, request, response);
	}
}

 

        //初始化layui,进度条依赖element
	    var element;
	  	layui.use('element', function(){
		  element = layui.element;
		});
	  	//执行任务
	  	$('#submitbtn').click(function(){
	  		//将进度条设置为05
	  		element.progress('executeprogress', '0%');
	  		//连接到websocket
	  		connect();
	  		//请求服务端进行执行任务
	  		$.post('${pageContext.request.contextPath }/excute.do',function(data){
	  			//服务端返回,任务执行完毕,关闭连接
	  			close();
			});
	  	});
	  	var ws;
	  	//连接到websocket
	  	function connect(){
	  		if ("WebSocket" in window) {
               ws = new WebSocket("${websocketserver}/testwebsocket");
                
               ws.onopen = function() {
            	   console.log("连接成功");
               };
                
               ws.onmessage = function (evt) { 
					//接收服务端的推送信息,改变进度条
                   element.progress('executeprogress', evt.data+'%');
               };
               ws.onclose = function() { 
                  // 关闭 websocket
                  console.log("连接已关闭..."); 
               };
            }
            
            else{
               // 浏览器不支持 WebSocket
               alert("您的浏览器不支持 WebSocket!");
            }
	  	}
	  	//关闭websocket
	  	function close(){
	  		ws.close();
	  	}

服务端的执行方法

    /**
	 * 任务执行方法(在实际应用中要改成自己的逻辑代码)
	*Title: execute
	*author:liuxuli
	*Description: 
	  * @param request
	  * @return
	 */
	@RequestMapping(value = "execute")
	public String execute(HttpServletRequest request) {
		
		for (int i = 0; i <= 100; i++) {
			//for循环只是个例子,在实际业务中百分比要进行实际的计算,这里的i就当是百分比
			//推送给用户
			TestWebsocket.sendMessage(request.getSession(), String.valueOf(i));
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		return "success";
	}

 

 

网站文章

  • Unity 革命性技术DOST入门一使用介绍

    Unity 革命性技术DOST入门一使用介绍

    Unity DOTS入门介绍 1.什么是DOTS? DOTS是Data-Oriented-Tech-Stack,官方中文翻译是:多线程式数据导向型技术堆栈。 DOST由以下三大核心成员组成: Enti...

    2024-04-01 02:00:27
  • Nginx性能优化

    Nginx性能优化

    1、首先我们需要了解性能优化要考虑哪些方面。2、然后我们需要了解性能优化必要用到的压力测试工具ab3、最后我们需要了解系统上有哪些注意和优化的点,以及nginx配置文件。

    2024-04-01 02:00:19
  • JavaScript之insertBefore()和自定义insertAfter()的用法。

    在JS图片库的第五版开发完后http://www.cnblogs.com/GreenLeaves/p/5691797.html#js_Five_Version我们发现一个问题,就是假设在图片列表之后还...

    2024-04-01 02:00:11
  • C++函数重载/运算符重载/函数对象/谓词/内建函数对象

    C++函数重载/运算符重载/函数对象/谓词/内建函数对象

    我们可以通过自己写成员函数来实现加号运算符的重载。但是这样呢,咱们写的函数名可能不同。这样就不统一了,所以的编译器就给我们取了一个通用的名字:operator+(oper-操作 + ator-表人 -> 操作数)。编译器还给咱们一个小礼物,我们可以不用调用这个函数了,直接用 + (当然这只是简化了,肯定调用了我们写的函数)

    2024-04-01 01:59:47
  • 网页设计中JS与Java的区别

    在各种网页制作技术论坛中,常常有人询问javascript与Java有什么区别,甚至有人误认为javascript就是Java.javascript与Java确实有一定的联系,但它们并不像我们想象的那样联系紧密,甚至可以肯定地说它们有很大的区别.什么是JavaScript ?JavaScript 是对 ECMA 262 语言规范的一种实现.本教程的目的就是引导您学习使用 JavaScrip...

    2024-04-01 01:59:40
  • 错误 LNK2038 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(main.obj 中)

    错误 LNK2038 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(main.obj 中)

    vs2019编译报错:错误 LNK2038 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(main.obj 中)

    2024-04-01 01:59:33
  • javacv实现音频文件转码g711a

    javacv实现音频文件转码g711a

    javacv 调用ffmgeg实现转码.输出g771a编码文件,gb28181

    2024-04-01 01:59:09
  • Boost.Asio C++ 网络编程之三:计时器

    引言文章的内容是翻译 《Boost.Asio C++ Network Programming》这本书。编译IDE环境是 vs2017计时器一些I/O操作需要一个超时时间。它只能应用在异步操作上(同步意味着阻塞,因此没有超时时间)。例如,下一条信息必须在100毫秒内从你的同伴那传递给你。bool read = false;void deadline_handler(const boost...

    2024-04-01 01:59:02
  • 1. 两数之和

    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。因为 nums[0] + nums[1] == 9 ,返回 [0, 1]。使用unordered_map (无序的map)集合存储整个数组,可以在logn的时间内找出。整数,并返回它们的数组下标。你可以想出一个时间复杂度小于。你可以按任意顺序返回答案。,请你在该数组中找出。

    2024-04-01 01:58:55
  • github访问失败的问题

    github访问失败的问题找到hosts文件。地址:C:\Windows\System32\Drivers\etc修改hosts文件。#github0.0.0.0 github.com0.0.0.0 ...

    2024-04-01 01:58:49