使用线程池模拟处理耗时任务,通过websocket提高用户体验
2014-07-24 10:10
519 查看
前言
在文章开始之前,询问一下大家平时工作中后端处理批量任务(耗时任务)的时候,前端是如何告知用户任务的执行情况的?楼主对这个问题想了下,决定使用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 + "执行完成"; } }
效果图:
![](http://images.cnitblog.com/i/411512/201407/231952549795912.gif)
前端js的代码就不贴了,用的是原生的websocket。
代码下载地址: https://github.com/fangjian0423/jetty8-websocket-demo
参考资料
http://zh.wikipedia.org/wiki/WebSocket/article/3924863.html
http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/
相关文章推荐
- 传智播客erp项目学习,使用Ajax提高用户体验效果
- 【译】MVC3 20个秘方-(13)使用Ajax Helper 提高用户体验
- vs2010 使用SignalR 提高B2C商城用户体验(二)
- Java:多线程,线程池,使用CompletionService通过Future来处理Callable的返回结果
- Java:多线程,线程池,使用CompletionService通过Future来处理Callable的返回结果
- 使用异步和事件代理提高用户体验(短信群发)
- 如何妥善处理WebBrowser对Javascript的错误问题,阻止JS弹出框,提高用户体验
- 使用SignalR 提高B2C商城用户体验1
- 模拟线程池,处理异步任务
- 404处理-提高用户体验
- 如何妥善处理WebBrowser对Javascript的错误问题,阻止JS弹出框,提高用户体验(原创)
- 使用e-tag来加快页面加载速度和提高用户体验
- Java:多线程,线程池,使用CompletionService通过Future来处理Callable的返回结果
- vs2010 使用SignalR 提高B2C商城用户体验(三)
- 使用异步页面,后台线程提高用户体验和服务器端性能
- Android使用后台线程提高用户体验
- 【转】使用jquery实现图片预加载提高页面加载速度和用户体验
- .net通过一般处理程序模拟用户控件数据保持、Ispostback 【第二版将html与ashx文件分开】
- 菜鸟学SSH(十九)——提高用户体验之404处理
- 【译】MVC3 20个秘方-(13)使用Ajax Helper 提高用户体验