标签:
大批量数据导入时,需要即时显示对文件的处理进度。考虑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/";
标签:
原文地址:http://www.cnblogs.com/diaoyan/p/5288439.html