大概需求:客户端通过TCP与服务端通讯,获取设备的运行状况。服务端通讯验证成功后会返回信息,但是一个线程之内至少需要30秒才能获取完毕。
大概流程:
前端web 1、登录通讯验证、login.html ,ip、端口、账号通过TCP与服务端通讯验证。
2、main.html 主界面,获取设备运行状况列表清单。问题:目前客户端web至少要等待30秒才能看到信息,请问有什么方法可以让前端实时显示服务端返回的数据,而不用等30秒后集中显示。获取服务端数据的代码大概如下:public class Equmain extends Thread{
Socket socket = null;
public Equmain(String ip,int port,String username,String password){
try{
socket = new Socket(host,port);
......
}catch{}
}
@overload
login();  //发送登录请求
heart();  //心跳信息
super.run();
try{
  //读取服务端返回的数据
            InputStream s = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(s,"gbk"));
            String line;
            StringBuffer message = new StringBuffer();  //一次完整的数据包
            while ((line = br.readLine()) != null) {
                message.append(line);
                if(line.contains("</Message>")){
                    //此时的message信息为一次完整的数据
                    String msg = message.toString();
                    message.setLength(0);
                    if(msg.contains("<DeviceParam>")&&msg.contains("<Type>RESPONSE</Type>")){
                        Device device = new DeviceStringToXML(msg).stringToXML();
                        deviceArrayList.add(device);   //累计到数组
                        System.out.println("查看设备详情");
                        System.out.println(device.toString());
                    }
             .....
       }
      catch(){...}
      finally{
         signal.countDown();  //线程执行完通知主程序
}
}这个线程里用while循环获取数据,整个线程大概需要30秒才能结束,然后返回数据给前端。(
前端用ajax  $.ajax({
        type: "post",
        url: 'DevServlet',
        //dataType:"json",
        data: data,
        error: function () {
            bootbox.alert({
                title:"登录提示",
                message: "服务繁忙,请稍候重试",
                size: 'small'
            });
        },
        success: function (result) {
            alert(result);
            if (result) {
               //返回的设备列表,然后加载到datatables表格
            } else {
                alert("连接超时,请重试");
            }
        }
    });
目前想到的一个方法是,线程中接收到一条设备数据立马发送给前端显示,但是测试java程序中如果线程不结束,就没法返回数据给前端。求解决代码或者思路,谢谢!!

解决方案 »

  1.   

    你这是想web端和服务端建立长链接吗?可以尝试下websocket技术。
      

  2.   

    轮询、Comet、websocket都可以实现,具体选择哪一种根据你的需要。
      

  3.   

    这。。用websocket不是完美解决么
      

  4.   

    websocket普通请求达不到你想要的效果的,当然你不想用websocket,也可以用长轮询的方式,如果没有消息就一直阻塞挂起,超时前端继续发起请求,如果有新的数据,则去查询数据
      

  5.   


    谢谢,去学习下websocket,轮询应该不行,信息是服务的主动推送过来的。客户端只负责接收就行。
      

  6.   


    websocket跟socket的主要区别在哪?  websocket需要跟线程配合使用吗? 谢谢
      

  7.   


    其他功能基本都已经用现在的SOCKET实现,如果这块用现有的SOCKET能否实现?   
    改用WEBSOCKET是不是是有代码都要重新做?
      

  8.   


    其他功能基本都已经用现在的SOCKET实现,如果这块用现有的SOCKET能否实现?   
    改用WEBSOCKET是不是是有代码都要重新做?
    看你代码怎么写的了,websocket应该除了第一步建立连接跟socket不一样,其他都一样
      

  9.   


    其他功能基本都已经用现在的SOCKET实现,如果这块用现有的SOCKET能否实现?   
    改用WEBSOCKET是不是是有代码都要重新做?
    看你代码怎么写的了,websocket应该除了第一步建立连接跟socket不一样,其他都一样谢谢,这个WEBSOCKETjar包哪里去找,我用的是IDEA2017.
      

  10.   


    其他功能基本都已经用现在的SOCKET实现,如果这块用现有的SOCKET能否实现?   
    改用WEBSOCKET是不是是有代码都要重新做?
    看你代码怎么写的了,websocket应该除了第一步建立连接跟socket不一样,其他都一样谢谢,这个WEBSOCKETjar包哪里去找,我用的是IDEA2017.
    jar包?现在用的比较多的就spring或者netty的websocket框架,当然只是其中一个小模块而已
      

  11.   

    你这个场景中,你的应用到页面是实时的,但设备到应用是非实时的,因为你是后台开线程去轮询设备的数据。解决方式就是让设备主动push到服务端,然后服务端主动push到页面。可能你的设备只支持简单的modlebus,只能服务端主动轮询,这样就永远不可能实时,当然你可以调整轮询的周期。还有你说的读一条发一条是可以的,当前线程一直读,另外一个线程池来发数据,异步的