websocket实例(显示文件导入处理进度)
2024-08-26 17:02:29
大批量数据导入时,需要即时显示对文件的处理进度。考虑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/";
最新文章
- 在Extjs中对日期的处理,以及在后端数据在SQL语句的判断处理
- 炉石传说 C# 开发笔记 (源代码整理公开)
- Java核心技术点之集合框架
- Linux企业集群用商用硬件和免费软件构建高可用集群PDF
- python web编程-CGI帮助web服务器处理客户端编程
- centos安装vsftp
- DIV重叠 如何优先显示(div浮在重叠的div上面)
- CentOS中配置LNMP环境打开提示File not found
- css盒子模型、文档流、相对与绝对定位、浮动与清除模型
- [jQuery编程挑战]006 生成一个倒计时效果
- 对于Android Service 生命周期进行全解析
- 第二章实例:Android窗口菜单显示
- 使用Material Design Tint和视图详解
- 最短路算法--SPFA+嵌套map
- luogu 1026 统计单词个数
- adb 转自github https://github.com/mzlogin/awesome-adb
- VGA原理
- sql server 2008 R2 备份还原到sql 2012
- react-native android打包
- java中身份证号和的银行卡的深度校验