websocket导入进度条

来源:互联网 发布:二叉树的遍历算法图解 编辑:程序博客网 时间:2024/06/03 20:55

1.封装websocket公用类

function websocket(){this.socket = null;this.code = new Date().getTime()+""+Math.floor(Math.random() * ( 1000 + 1));this.options = {url:getWsPath,dataType:"json",onmessage:function(msg){return msg;},onopen:function(msg){return msg;},onclose:function(msg){return msg;},onerror:function(msg){return msg;}};}websocket.prototype.init = function(options){//判断当前浏览器是否支持WebSocket  if (!window.WebSocket) {  window.WebSocket = window.MozWebSocket;}if(window.WebSocket){  this.socket = new WebSocket(getWsPath()+"/"+this.code);}else{$CommonUI.alert('当前浏览器 不支持 websocket');  return;}//如果存在配置信息if(options){//初始化默认属性options = $.extend(this.options,options);//连接发生错误的回调方法  this.socket.onerror = function (event) {  options.onerror(event.data);};   //连接成功建立的回调方法  this.socket.onopen = function (event) {  options.onopen(event.data); }   //接收到消息的回调方法  this.socket.onmessage = function (event) {  //当返回配置为json的时候则配置为json    if(options.dataType=="json"){    options.onmessage($.parseJSON(event.data));    }else{    options.onmessage(event.data);    }}  //连接关闭的回调方法  this.socket.onclose = function (event) {  options.onclose(event.data);} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。  window.onbeforeunload = function () {  if(this.socket){this.socket.close();  }}}}//发送消息websocket.prototype.send = function(msg){if (!window.WebSocket) { return; }    if (this.socket.readyState == WebSocket.OPEN) {    if(typeof msg == "string"){    this.socket.send(msg);    }else{    msg["code"] = this.code;    msg.paramsIn = JSON.stringify(msg.paramsIn);    this.socket.send(JSON.stringify(msg));    }    } else {        $CommonUI.alert("连接没有打开!");    }};//获取websocket路径function getWsPath(){var host = window.location.host;//主机IP:portvar path = window.document.location.pathname;//端口后的路径var projectName = path.substring(0,path.substr(1).indexOf("/")+1);//项目名return "ws://"+host+projectName+"/websocket";}

2.前端调用websocket

var websocket = new websocket();websocket.init({onmessage:function(msg){$CommonUI.getProgressBar('#importProgress').progressbar('setValue', msg);}})

3.后端websocket的支持

package com.dhcc.isccore.common.websocket;import java.io.IOException;import java.util.concurrent.ConcurrentHashMap;import javax.websocket.OnClose;import javax.websocket.OnError;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.Session;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import com.dhcc.isccore.dto.websocket.WebsocketDto;@ServerEndpoint("/websocket/{code}") public class WebSocketListen {//用于记录接入的websocket连接private static ConcurrentHashMap<String,WebsocketDto> websocketMap = new ConcurrentHashMap<String,WebsocketDto>();    /**      * 连接建立成功调用的方法      *       * @param session      * 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据      */      @OnOpen      public void onOpen(@PathParam("code") String code,Session session) {      WebsocketDto websocketDto = new WebsocketDto();    websocketDto.setCode(code);    websocketDto.setSession(session);    websocketMap.put(code, websocketDto);    }        /**      * 连接关闭调用的方法      */      @OnClose      public void onClose(@PathParam("code") String code) {      websocketMap.remove(code);    }        /**      * 收到客户端消息后调用的方法      *       * @param message      * 客户端发送过来的消息      * @param session      * 可选的参数      */      @OnMessage      public void onMessage(String message, Session session) {      }        /**      * 发生错误时调用      *       * @param session      * @param error      */      @OnError      public void onError(Session session, Throwable error) {          error.printStackTrace();      }        //发送消息    public static void sendMessage(String code,String message) throws IOException {      Session session = websocketMap.get(code).getSession();        session.getBasicRemote().sendText(message);      }  public static ConcurrentHashMap<String, WebsocketDto> getWebsocketMap() {return websocketMap;}public static void setWebsocketMap(ConcurrentHashMap<String, WebsocketDto> websocketMap) {WebSocketListen.websocketMap = websocketMap;}}

注意:1.websocket只支持get请求;
           2.websocket可以通过@PathParam(参数名)获取到请求传递的参数;
           3.参数名实在@ServerEndpoint中通过{参数名}定义的。

这里使用传入的code唯一标识一次请求,其他地方可根据该code获取到当前session并发送消息到前台。

4.Websocket定义

package com.dhcc.isccore.dto.websocket;import javax.websocket.Session;public class WebsocketDto{/**  * 字段:      字段名称* @Fields serialVersionUID : TODO */private Stringcode;//客户端传入的唯一标识private int totalNum; //总数量private int handleNum = 0;//当前操作数量private Session session;//当前websocket的sessionpublic int getTotalNum() {return totalNum;}public void setTotalNum(int totalNum) {this.totalNum = totalNum;}public int getHandleNum() {return handleNum;}public void setHandleNum(int handleNum) {this.handleNum = handleNum;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public Session getSession() {return session;}public void setSession(Session session) {this.session = session;}}

5.后端返回进度

<pre name="code" class="java">//websocket开始WebsocketDto webSocketDto = WebSocketListen.getWebsocketMap().get(code);int handleNum = webSocketDto.getHandleNum();handleNum = handleNum + i;String progress = (int)(handleNum*100/webSocketDto.getTotalNum())+"";WebSocketListen.sendMessage(code, progress);//websocket结束
这里i是本次插入数据库的数据量

6.进度条设计原理

  a.初始化定义一个长连接的websocket,用于更新进度。
  b.当导入的时候读取当前导入的总条数。
  c.当每插入总数的1%数据时发送一个进度回前端,前端渲染该进度,直到100%完成。

注意:每一次数据传输websocket都会新建一个通道,发送一次ws请求,在请求完成后自动关闭该websocket连接。


0 0
原创粉丝点击