• ajax实现长连接


    项目需求:需要实时的读取日志文件里的数据,并且使用Echart实时更新折线图。

    使用ajax实现客户端与服务器端的数据传输。

    目的:我想通过ajax与服务器建立一个长连接,服务器会不断的传输数据给前台,由于日志不断的更新,我想把新的数据不断的传给前台。

    设计:本来想着使用服务器使用一个死循环去读取日志信息,一个线程去提交数据。

    参考:https://www.cnblogs.com/hoojo/p/longPolling_comet_jquery_iframe_ajax.html

    发现与想象的不同,这个长连接并不是不间断的连接,而是连接成功一次,传输完数据断开,再重新建立新连接,会重新去调用函数。

    由于一开始的理解错误,因为用死循环去读取日志,这样会导致每次都会调用一次函数,这样会开启多个死循环,打开任务管理器,发现CPU和内存的不断飙升,所以每次连接都要跳出死循环。

    这样会产生新问题,每次都要重新读日志。

    设计,保存上一次读取的位置,避免重头开始。

    前台代码:

    //异步请求获取数据,递归调用自己,实现长连接
               
    function longPolling() {
        $.ajax({
            type:'POST',
            url:'get',
            dataType:'json',
            data:postData,
            timeout: 20000,
            success:function(result){
                if(result){
                    //保存文件指针,再传给后台                
                    postData.lastTimeFileSize = result.pointer    
                    //添加数据
                    for(var i=0;i<result.axis.length;i++){
                        datax.push(result.axis[i]);
                        datay.push(result.series[0].data[i]);
                    }
                    //画图
                    myChart.hideLoading();
                    myChart.setOption({
                         xAxis: {
                             data: datax
                         },
                         series: [{
                             // 根据名字对应到相应的系列
                             name: 'alpha.water',
                             data: datay
                         }]
                    }); 
                    
                    longPolling();
                }
             },
            error:function(XMLHttpRequest, textStatus, errorThrown){            
                console.error("加载数据失败");                    
                longPolling();        
            },
                        
        });
        
    };

    后台代码:

    发送数据

    
    

    public class getData extends HttpServlet {
    File logFile = new File("D:\workspace\drawChart\src\read_log\log.txt");
    private long lastTimeFileSize = 0; // 上次文件大小


    //
    打包数据为Json格式传给前台 public void pickData(HttpServletRequest request,HttpServletResponse response,Float message[][],long pointer) throws ServletException, IOException { List<String> legend = new ArrayList<String>(Arrays.asList(new String[]{"alpha.water"})); //x轴时间 List<Float> axis = new ArrayList<Float>(Arrays.asList(message[0])); List<Series> series=new ArrayList<Series>(); //series series.add(new Series("alpha.water","line",new ArrayList<Float>(Arrays.asList(message[1])))); //更改下一行代码,添加多个series Echarts echarts = new Echarts(legend,axis,series,pointer); ObjectMapper objectMapper = new ObjectMapper(); String str = objectMapper.writeValueAsString(echarts); System.out.println(objectMapper.writeValueAsString(echarts)); response.setContentType("text/html;charset=utf-8"); //发送数据 PrintWriter out = response.getWriter(); out.write(str); System.out.println("发送post方法。。。。。。。。。。"); out.flush(); out.close(); }

    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
            String regEx = "(-?\d+)(\.\d+)?";
            String regEx0 = "^Time = [0-9]\d*\.\d*|0\.\d*[1-9]\d*$";                
            Pattern pattern = Pattern.compile(regEx);
            Pattern pattern0 = Pattern.compile(regEx0);
            float alpha = 0;
            float p_rgh = 0;
            float omega = 0;
            float k = 0;
            float DTime = 0;
            //用来保存所有数据的二维数组
            Float message[][] = new Float[14][5];    
            //计数器,个数据传一次
            int flag = -1;        
            //获取保存的上一次读取的位置
            String str = request.getParameter("lastTimeFileSize");        
            lastTimeFileSize = Long.parseLong(str);
            System.out.println(lastTimeFileSize);          
                     
            try {
                long len = logFile.length();
                System.out.println(len);
                if(lastTimeFileSize >= len){
                    lastTimeFileSize = len;
                    try {
                        //如果读取的速度超过写的速度,等待5秒
                        Thread.sleep(5000);
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }                              
                }else{
                     RandomAccessFile randomFile = new RandomAccessFile(logFile, "r");     
                     randomFile.seek(lastTimeFileSize);                    
                     String tmp = null;                                                                 
                     while ((tmp = randomFile.readLine()) != null) {                                                                       
                         //正则匹配时间                                           
                         Matcher matcher0 = pattern0.matcher(tmp);
                         if(matcher0.lookingAt()){                               
                             if(flag==4){                                
                                //记录读取文件的位置
                                lastTimeFileSize = randomFile.getFilePointer();
                                System.out.println(lastTimeFileSize);
                                //传数据                                
                                 try {
                                    Thread.sleep(3000);
                                    //由于是根据time决定是否提交,所以提交5次需要读6个time,文件指针会只在time后面,因此要倒回
                                    lastTimeFileSize -= 50;
                                    pickData(request,response,message,lastTimeFileSize);
                                    
                                } catch (InterruptedException e1) {
                                    e1.printStackTrace();
                                }  
                                randomFile.close();
                                flag = -1;
                                break;
                             }                         
                             DTime = Float.parseFloat(tmp.split("=")[1]);                                                     
                             flag++;
                             message[0][flag] = DTime;                            
                         }
                         //yangmo
                         //找到 alpha p_rgh Omega k;
                         else if((tmp.startsWith("smoothSolver:  Solving for alpha.water")))
                         {
                             String[] splitAddress = tmp.split(",")[1].split("=");                         
                             alpha = Float.parseFloat(splitAddress[1]);  
                             System.out.println(flag);
                             message[1][flag] = alpha;  
                             //System.out.println(alpha);
                             
                         }
                         else if((tmp.startsWith("GAMG:  Solving for p_rgh")))
                         {
                             String[] splitAddress = tmp.split(",")[1].split("=");                             
                             p_rgh = Float.parseFloat(splitAddress[1]);
                             message[2][flag] = p_rgh;
                             //System.out.println(p_rgh);
                         }
                         else if((tmp.startsWith("smoothSolver:  Solving for omega")))
                         {
                             String[] splitAddress = tmp.split(",")[1].split("="); 
                             omega = Float.parseFloat(splitAddress[1]);
                             message[3][flag] = omega;
                             //System.out.println(omega);
                         }
                         else if((tmp.startsWith("smoothSolver:  Solving for k")))
                         {
                             String[] splitAddress = tmp.split(",")[1].split("="); 
                             k = Float.parseFloat(splitAddress[1]);
                             message[4][flag] = k;
                             //System.out.println(k);
                         }
                         //找到 x,y,z
                         else if(tmp.equals("Sum of forces"))
                         {
                             int j = 5;
                             for(int i=1;i<=3;i++){                              
                                 String line = randomFile.readLine();                                                              
                                 Matcher matcher = pattern.matcher(line); 
                                 //正则匹配数值
                                 while(matcher.find()){                                 
                                     message[j][flag] = Float.parseFloat(matcher.group());
                                     j++;
                                 }                                                                                                 
                             }                           
                         }                        
                     } 
                     //读到文件的末尾需要把剩余数据的提交
                     if(flag>-1){
                         //提交最后的数据
                         lastTimeFileSize = randomFile.getFilePointer();
                         lastTimeFileSize -= 50;
                         pickData(request,response,message,lastTimeFileSize);
                     }else
                     {
                         //等待,可以有效的避免前台无间歇的询问导致CPU占用增大
                         try {                        
                             Thread.sleep(10000);
                         } catch (InterruptedException e1) {
                             e1.printStackTrace();
                         }                        
                     }
                }           
            } catch (IOException e) {               
                e.printStackTrace();
            }finally{
                //其它操作            
            }         
        }  
    }
    
    
    
     

    红色标记内容是相关内容

    注意:类中如果使用构造器去传递文件的路径名,则ajax请求会失败

    web.xml

    
    

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
    <servlet>
    <description></description>
    <display-name>getData</display-name>
    <servlet-name>getData</servlet-name>
    <servlet-class>read_log.getData</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>getData</servlet-name>
    <url-pattern>/get</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
    <welcome-file>chart.jsp</welcome-file>
    </welcome-file-list>
    </web-app>

    
    
  • 相关阅读:
    RocketMQ 负载均衡
    RocketMQ 介绍及核心概念
    PagView动画
    andriod 视频播放方案
    Andriod 插件化初识
    Android 加载库的方式
    AIDL服务死亡代理
    Android O 创建后台Service
    IntentService
    Activity Dialog 进出动画
  • 原文地址:https://www.cnblogs.com/zhxuxu/p/9745462.html
Copyright © 2020-2023  润新知