zoukankan      html  css  js  c++  java
  • 使用线程池模拟处理耗时任务,通过websocket提高用户体验

    前言

    在文章开始之前,询问一下大家平时工作中后端处理批量任务(耗时任务)的时候,前端是如何告知用户任务的执行情况的?

    楼主对这个问题想了下,决定使用websokect将这一过程展现给用户。

    于是就有了这篇文章,跟大家一起学习。

    WebSocket简单介绍

    WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。 WebSocket通信协议于2011年被IETF定为标准 RFC 6455,WebSocketAPI被W3C定为标准。

    在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

      ----------以上文字摘自于Wiki对WebSocket的介绍。 

    简单来说,WebSocket就是浏览器与服务器之间进行通讯的一种技术。

    关于WebSocket出现的背景及原理,大家可看wiki中的介绍。

    实例讲解

    本文讲解的实例使用java语言编写,web服务器使用jetty8。

    先看下对应的Servlet和WebSocket代码:

    Servlet:

    @WebServlet(name = "main", urlPatterns = "/main.do")
    public class MainServlet extends WebSocketServlet {
    
        public WebSocket doWebSocketConnect(HttpServletRequest httpServletRequest, String s) {
            return new TaskWebSocket();
        }
        
    }

    WebSocket使用Task对象模拟耗时任务,用线程池进行处理:

    public class TaskWebSocket implements WebSocket.OnTextMessage {
    
        private Connection conn;
    
        private ExecutorService executorService;
        private CompletionService completionService;
    
        private Random random = new Random();
        
        public TaskWebSocket() {
            executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
            completionService = new ExecutorCompletionService<String>(executorService);
        }
        
        
        public void onMessage(String s) {
            try {
                conn.sendMessage("开始执行任务");
                int taskNum = 4;
                for(int i = 0; i < taskNum; i ++) {
                    Task task = new Task(random.nextInt(20), conn, String.valueOf(i + 1));
                    completionService.submit(task);
                }
                for(int i = 0; i < taskNum; i ++) {
                    String result = completionService.take().get();
                    conn.sendMessage(result);
                }
                conn.sendMessage("任务执行完毕");
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println("error");
            }
        }
    
        public void onOpen(Connection connection) {
            System.out.println("on Open");
            this.conn = connection;
        }
    
        public void onClose(int i, String s) {
            System.out.println("on Close");
        }
    
        
    }
    
    class Task implements Callable<String> {
    
        private int sleepSec;
        private WebSocket.Connection conn;
        private String name;
    
        public Task(int sleepSec, WebSocket.Connection conn, String name) {
            this.sleepSec = sleepSec;
            this.conn = conn;
            this.name = name;
        }
    
        public String call() throws Exception {
            conn.sendMessage("任务(" + name + ")开始执行, 该任务大概会执行" + sleepSec + "秒");
            Thread.sleep(sleepSec * 1000);
            return "任务" + name + "执行完成";
        }
    
    }

     效果图:

    前端js的代码就不贴了,用的是原生的websocket。

    代码下载地址: https://github.com/fangjian0423/jetty8-websocket-demo

    参考资料

    http://zh.wikipedia.org/wiki/WebSocket

    http://redstarofsleep.iteye.com/blog/1307608

    http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/

  • 相关阅读:
    docker-compose.yml容器网络
    docker-compose搭建redis集群
    docker-compose简易搭建rabbitmq
    docker仓库快速搭建
    CNN是怎样一步步工作的?
    全连接层分类的原理
    vector中erase()与insert()用法
    MySQL安装教程
    红黑树与AVL树比较
    C++内存管理(超长,例子很详细,排版很好)
  • 原文地址:https://www.cnblogs.com/fangjian0423/p/jetty-websocket-demo.html
Copyright © 2011-2022 走看看