如何干净的实现Android/Java Socket 长连接通信

 我来答
好程序员
2016-03-16 · HTML5前端培训/大数据培训/Java
好程序员
好程序员是IT高端课程培训基地,从平凡到卓越,为梦想而拼搏。
向TA提问
展开全部

所谓长连接,它通常包含以下几个关键过程:

  1. 轮询的建立        
    建立轮询的过程很简单,浏览器发起请求后进入循环等待状态,此时由于服务器还未做出应答,所以HTTP也一直处于连接状态中。        
    2. 数据的推送        
    在循环过程中,服务器程序对数据变动进行监控,如发现更新,将该信息输出给浏览器,随即断开连接,完成应答过程,实现“服务器推”。        
    3. 轮询的终止        
    轮询可能在以下3种情况时终止:        
      3.1. 有新数据推送        
       当循环过程中服务器向浏览器推送信息后,应该主动结束程序运行从而让连接断开,这样浏览器才能及时收到数据。        
      3.2. 没有新数据推送        
       循环不能一直持续下去,应该设定一个最长时限,避免WEB服务器超时(Timeout),若一直没有新信息,服务器应主动向浏览器发送本次轮询无新信息的正常响应,并断开连接,这也被称为“心跳”信息。        
      3.3. 网络故障或异常        
       由于网络故障等因素造成的请求超时或出错也可能导致轮询的意外中断,此时浏览器将收到错误信息。        
    4. 轮询的重建        
    浏览器收到回复并进行相应处理后,应马上重新发起请求,开始一个新的轮询周期。

客户端代码片段

                  <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>



     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">



     <html>



         <head>



             <meta http-equiv="pragma" content="no-cache">



             <meta http-equiv="cache-control" content="no-cache">



             <meta http-equiv="author" content="hoojo & http://hoojo.cnblogs.com">



             <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />



             <%@ include file="/tags/jquery-lib.jsp"%>



             



             <script type="text/javascript">



                 $(function () {



                 



                     window.setInterval(function () {



                     



                         $.get("${pageContext.request.contextPath}/communication/user/ajax.mvc",



                             {"timed": new Date().getTime()},



                             function (data) {



                                 $("#logs").append("[data: " + data + " ]<br/>");



                         });



                     }, 3000);



                     



                 });



             </script>



         </head>



         



         <body>



             <div id="logs"></div>



         </body>



     </html>

服务器端代码

   

   

   
     @RequestMapping("/ajax")



     public void ajax(long timed, HttpServletResponse response) throws Exception {



          PrintWriter writer = response.getWriter();



         



          Random rand = new Random();



          // 死循环 查询有无数据变化



          while (true) {



              Thread.sleep(300); // 休眠300毫秒,模拟处理业务等



              int i = rand.nextInt(100); // 产生一个0-100之间的随机数



              if (i > 20 && i < 56) { // 如果随机数在20-56之间就视为有效数据,模拟数据发生变化



                  long responseTime = System.currentTimeMillis();



                  // 返回数据信息,请求时间、返回数据时间、耗时



                  writer.print("result: " + i + ", response time: " + responseTime + ", request time: " + timed + ", use time: " + (responseTime - timed));



                  break; // 跳出循环,返回数据



              } else { // 模拟没有数据变化,将休眠 hold住连接



                  Thread.sleep(1300);



              }



          }



         



     }

星月小木木
2016-01-23 · TA获得超过3.2万个赞
知道大有可为答主
回答量:2.4万
采纳率:0%
帮助的人:9904万
展开全部
  现编这个就是个多线程服务器,只要在client不释放连接,服务器端的run里边写while(TRUE)循环,那么就可以长期连接。
  class ConnectionThread extends Thread{
  Socket client;
  int counter;
  public ConnectionThread(Socket cl,int c){
  client = cl;
  counter= c;
  }
  @Override
  public void run()
  {
  try{
  String destIP=client.getInetAddress().toString();
  int destport =client.getPort();
  PrintStream outstream=new PrintStream(client.getOutputStream());
  DataInputStream instream=new DataInputStream(client.getInputStream());
  String inline=instream.readLine();
  }//try
  catch(IOException e){System.out.println(e);}
  }//run
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
马特丶达蒙
2017-06-07 · 超过12用户采纳过TA的回答
知道答主
回答量:36
采纳率:0%
帮助的人:23.6万
展开全部
看你用什么协议
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式