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

实现思路

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

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";
	}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员老牛了laoliu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值