如何干净的实现Android/Java Socket 长连接通信
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何干净的实现Android/Java Socket 长连接通信相关的知识,希望对你有一定的参考价值。
所谓长连接,它通常包含以下几个关键过程:
轮询的建立
建立轮询的过程很简单,浏览器发起请求后进入循环等待状态,此时由于服务器还未做出应答,所以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);
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本回答被提问者采纳 参考技术B 看你用什么协议
Tomcat 上的 Websockets:如何干净地关闭服务器?
【中文标题】Tomcat 上的 Websockets:如何干净地关闭服务器?【英文标题】:Websockets on Tomcat: how to shutdown the server cleanly? 【发布时间】:2015-08-07 08:35:37 【问题描述】:如何拦截服务器上运行的端点的关闭事件(例如 servlet 的销毁方法)以用于日志记录或其他目的?
【问题讨论】:
你找到答案了吗? 【参考方案1】:Spring 4 Java 配置:
实现 SmartLifecycle(使用基于 Java 的配置时,或将 Java 代码转换为 XML):
@Configuration
public class CycleBean implements SmartLifecycle
public CycleBean()
@Override
public boolean isRunning()
return true;
@Override
public void start()
@Override
public void stop()
//when stopped call
@Override
public int getPhase()
return 0;
@Override
public boolean isAutoStartup()
return true;
@Override
public void stop(Runnable arg0)
//
见http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html第4.6段自定义bean的性质,如:
<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
<!-- timeout value in milliseconds -->
<property name="timeoutPerShutdownPhase" value="10000"/>
</bean>
【讨论】:
感谢您的快速回复。但是我的上下文没有 spring 框架,只有一个在 Tomcat webapp 中运行的 EndPoint。 不好意思,我没听说过EndPoint
所以没把它当成环境
顺便说一句,我拼错了:我应该写 Endpoint
http://docs.oracle.com/javaee/7/api/javax/websocket/Endpoint.html
但是...我会说覆盖onClose(Session session, EndpointConfig config)
方法。首先(如果可能)调用super.onClose(session, closeReason)
,然后调用日志记录方法
谢谢丹尼尔森。但是,onClose(Session session, CloseReason reason)
方法是为每个关闭的会话触发的,而不是在端点实例关闭时触发。而且我找不到方法onClose(Session session, EndpointConfig config)
来覆盖...它应该属于哪个类?以上是关于如何干净的实现Android/Java Socket 长连接通信的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 中干净地叠加 ScrollableViews
java 网络编程中 tcp连接问题。 例如编写聊天室 , c/s结构的c和s端都是不间断实现请求--响应 。