大批量数据导入时,需要即时显示对文件的处理进度。考虑ajax轮询太浪费资源,使用websocket实现。

项目使用Spring MVC(3.1),与websocket结合要求版本4.0以上。所以没有使用Spring提供的websocket。

1.依赖Tomcat 7 或者 J2EE 7

maven导入:

<!-- webscoket start -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket-api</artifactId>
<version>7.0.47</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.0</version>
</dependency>
<!-- webscoket end -->

2.服务端

  工具类,存储唯一key和连接

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import javax.websocket.Session; public class WebsocketSessionUtils { public static Map<String, Session> clients = new ConcurrentHashMap<>(); public static void put(String batchKey, Session session) {
clients.put(batchKey, session);
} public static Session get(String batchKey) {
return clients.get(batchKey);
} public static void remove(String batchKey) {
clients.remove(batchKey);
} public static boolean hasConnection(String batchKey) {
return clients.containsKey(batchKey);
} }

  websocket处理类,不要添加业务逻辑

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; @ServerEndpoint("/websocket.ws/{batchKey}")
public class WebsocketEndPoint {
private static Log log = LogFactory.getLog(WebsocketEndPoint.class); @OnOpen
public void onOpen(@PathParam("batchKey") String batchKey, Session session) {
log.info("Websocket Start Connecting:" + batchKey);
WebsocketSessionUtils.put(batchKey, session);
} @OnMessage
public String onMessage(@PathParam("batchKey") String batchKey,
String message) {
return "Got your message (" + message + ").Thanks !";
} @OnError
public void onError(@PathParam("batchKey") String batchKey,
Throwable throwable, Session session) {
log.info("Websocket Connection Exception:" + batchKey);
log.info(throwable.getMessage(), throwable);
WebsocketSessionUtils.remove(batchKey);
} @OnClose
public void onClose(@PathParam("batchKey") String batchKey, Session session) {
log.info("Websocket Close Connection:" + batchKey);
WebsocketSessionUtils.remove(batchKey);
} }

3.客户端

  使用js闭包封装websocket,导入websocket.js

var myWebSocket = (function() {
var mySocket = {};
mySocket.tryTime = 0;
mySocket.webSocketUrl = null;
mySocket.batchKey = null;
mySocket.webSocket = null;
mySocket.initSocket = function() {
if (!window.WebSocket) {
// alert("Your browsers don't support websocket.");
return false;
}
mySocket.webSocket = new WebSocket(mySocket.webSocketUrl + mySocket.batchKey);
mySocket.webSocket.onmessage = function(msg) {
console.log(msg);
};
mySocket.webSocket.onerror = function(event) {
console.log(event);
};
mySocket.webSocket.onopen = function(event) {
console.log(event);
};
mySocket.webSocket.onclose = function() {
if (mySocket.tryTime < 10) {
setTimeout(function() {
webSocket = null;
mySocket.tryTime++;
mySocket.initSocket();
}, 500);
} else {
mySocket.tryTime = 0;
}
};
};
mySocket.closeSocket = function() {
if (mySocket.webSocket) {
mySocket.webSocket.close();
}
};
return mySocket;
})();

  在ajax执行时启动websocket,使用timestamp作为唯一key。

var commissionWebsocketUrl = "ws://${remote_websocket}/commission/websocket.ws/";
        var timestamp=new Date().getTime();
$.ajax({
type : "POST",
url : trialUrl+"?batchKey="+timestamp,
data : $("#batchUploadForm").serialize(),
dataType : "html",
beforeSend: function(xhr) {
var countDiv = $('#loading #countDiv');
if(countDiv.length==0){
countDiv =$("<div id='countDiv'></span>");
$('#loading').append(countDiv);
}
$('#loading').show();
myWebSocket.webSocketUrl = commissionWebsocketUrl;
myWebSocket.batchKey = timestamp;
myWebSocket.initSocket();
myWebSocket.webSocket.onmessage = function(msg) {
countDiv.html("mTusker is processing date,Please wait... "+msg.data);
};
},
complete: function(){
$('#loading').hide();
myWebSocket.closeSocket();
},
success : function(data) {
$("#trialInfoPopup").html(data);
mydialog = $("#trialInfoPopup").dialog({
position: ['center',100] ,width : 1400,height: 600,
modal : true,
title : "Batch Upload Trial"
});
}
});

  java项目作为客户端

import java.io.IOException;

import javax.websocket.ClientEndpoint;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session; @ClientEndpoint
public class WebsocketClient {
@OnOpen
public void onOpen(Session session) {
System.out.println("Connected to endpoint:" + session.getBasicRemote());
try {
session.getBasicRemote().sendText("Hello");
} catch (IOException ex) {
}
} @OnMessage
public void onMessage(String message) {
System.out.println(message);
} @OnError
public void onError(Throwable t) {
t.printStackTrace();
}
}
import java.io.IOException;
import java.net.URI; import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer; public class WebsocketApp {
private static String webUrl = "localhost"; public static void send(String batchKey, String message) {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
String uri = "ws://"+webUrl+"/websocket.ws/" + batchKey;
System.out.println("Connecting to" + uri);
try {
Session session = WebsocketSessionUtils.get(batchKey);
if (session == null) {
session = container.connectToServer(WebsocketClient.class, URI.create(uri));
WebsocketSessionUtils.put(batchKey, session);
}
session.getBasicRemote().sendText(message);
} catch (DeploymentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} public static String getWebUrl() {
return webUrl;
} public static void setWebUrl(String webUrl) {
WebsocketApp.webUrl = webUrl;
} }

  把导入文件处理部分,当做java项目客户端,处理过程中调用websocket

                int num = 0;
for(Map<String,String> rowInfo : rows){
WebsocketApp.send(batchKey, num++ + "/" + rows.size());
......
}

  由此实现在处理文件过程中即时发送处理进度。

注: 当使用https时需要改为

var commissionWebsocketUrl = "wss://${remote_websocket}/commission/websocket.ws/";

websocket实例(显示文件导入处理进度)的更多相关文章

  1. Websocket实例

    C#版Websocket实例 websocket有java.nodejs.python,Php等等版本,我使用的是C#版本,服务器端是Fleck,github地址:https://github.com ...

  2. C#版Websocket实例

    C#版Websocket实例   Demo地址:www.awbeci.xyz websocket有java.nodejs.python,Php等等版本,我使用的是C#版本,服务器端是Fleck,git ...

  3. Bootstrap历练实例:动画的进度条

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  4. Bootstrap历练实例:堆叠的进度条

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. Bootstrap历练实例:默认的进度条

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  6. requests实现文件下载, 期间显示文件信息&下载进度_python3

    requests实现文件下载, 期间显示文件信息&下载进度 """使用模块线程方式实现网络资源的下载 # 实现文件下载, 期间显示文件信息&下载进度 # ...

  7. WebSocket入门教程(五)-- WebSocket实例:简单多人聊天室

    from:https://blog.csdn.net/u010136741/article/details/51612594 [总目录]   WebSocket入门教程--大纲   [实例简介]   ...

  8. Java web实时进度条整个系统共用(如java上传进度条、导入excel进度条等)

    先上图: 这上文件上传的: 这是数据实时处理的: 1:先说说什么是进度条:进度条即计算机在处理任务时,实时的,以图片形式显示处理任务的速度,完成度,剩余未完成任务量的大小,和可能需要处理时间,显示方式 ...

  9. HTML5 CSS3 诱人的实例 : 网页载入进度条的实现,下载进度条等

    今天给大家带来一个比較炫的进度条,进度条在一耗时操作上给用户一个比較好的体验,不会让用户认为在盲目等待,对于没有进度条的长时间等待,用户会任务死机了,毫不犹豫的关掉应用:一般用于下载任务,删除大量任务 ...

随机推荐

  1. qt 环境下mapx组件的鼠标跟踪

    经过两天的研究mapx组件人坐标转换还是没有转换成功,因为不管怎么变,定点转换的经纬度坐标始终与期望的值有较大的偏差.最后还是想老大请教了一下,划了半天功夫就研究出来了(不愧是老大,仰慕之情犹如滔滔江 ...

  2. JavaScript简介及示例

    JavaScript简介及使用 一.简介 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛 ...

  3. Linux 文件与目录管理

    Linux 文件与目录管理 我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /. 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们. 在开始本教程前我们需要先知道什么是绝对 ...

  4. bugfree安装 centos

    bugfree团队早已不做支持,转作禅道管理了,关于其中恩怨可以参见http://www.bugfree.cn/ 组里同事要用此做管理,所以写此文档,以备后用 ==================== ...

  5. EasyUI TextBox的onkeypress事件

    关于EasyUI TextBox的事件好像不多,像keypress,keydown在textbox的事件里都没有,所以要用这些事件要采取一些特殊的方法,今天用到了这些就记录一下,有两种方法 方法1: ...

  6. 初学python之安装Jupyter notebook

    一开始安装python的时候,安装的是最新版的python3.6的最新版.而且怕出问题,选择的都是默认安装路径.以为这样总不会出什么问题.一开始确实这样,安装modgodb等一切顺利.然而在安装jup ...

  7. 基于WDF的PCI/PCIe接口卡Windows驱动程序(5)-如何为硬件移植驱动程序

    原文地址:http://www.cnblogs.com/jacklu/p/6139347.html 正如前几篇博客所说,使用WDF开发PCIe驱动程序是我本科毕业设计的主要工作.在读研的两年,我也分别 ...

  8. MVC过滤器详解

    MVC过滤器详解   APS.NET MVC中(以下简称"MVC")的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理. ...

  9. iOS实现屏幕旋转

    iOS实现屏幕旋转有两种方式 1. 应用本身支持 2. 手动旋转UIView (这种方式我没找到旋转 系统控件的方法 如:键盘.导航.UIAlertView) 如果你只是要把竖屏的播放器,做成支持横屏 ...

  10. 使用openssl实现ECDSA签名以及验证功能(附完整测试源码)

    突然找到数年前写的这段代码,当是因为对密码学几乎不怎么了解踩了一些坑,现在开源出来方便大家直接利用. ECDSA的全名是Elliptic Curve DSA,也就是椭圆曲线DSA,由于椭圆曲线的复杂性 ...