长连接服务器servlet:
public class LongTest extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss E");
String date_str = df.format(new Date());
writerResponse(response, date_str, "showServerTime");// msg是test.jsp中的那个js方法的名称
}
return;
}
protected void writerResponse(HttpServletResponse response, String body, String client_method) throws IOException {
StringBuffer sb = new StringBuffer();
sb.append("<script type=\"text/javascript\">//<![CDATA[\n");
sb.append(" parent.").append(client_method).append("(\"").append(body).append("\");\n");
sb.append("//]]></script>");
// System.out.println(sb.toString());
// response.setContentType("text/html;charset=GBK");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
response.addHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");
response.setHeader("Cache-Control", "pre-check=0,post-check=0");
response.setDateHeader("Expires", 0);
response.getWriter().write(sb.toString());
response.flushBuffer();
}
}
测试客户端:
try {
//确定服务地址
URL url = new URL("http://touch-pingdembp:8080/apperror/LongTest");
InputStream in=url.openStream();
int n = -1;
byte[] b = new byte[1024];
//从服务端读取数据并打印
int readlength = n = in.read(b);
while(readlength!=-1)
{
String s=new String(b,0,n, "UTF-8");
System.out.println(s);
readlength = n = in.read(b);
}
} catch (IOException e) {
LogUtil.print("连接断开!");
e.printStackTrace();
}
一般的servlet写出数据时是这样的:
<p class="p1"><span> </span>PrintWriter out;</p><p class="p1"><span> </span><span> </span><span> </span>out = response.getWriter();</p><span style="white-space:pre"> </span>out.print(json);
out.flush();
out.close();
close之后,网络请求出结果,长链接不同,colse是很少发生的,所以一直在写出数据,客户端需要不断的read数据并处理,而不是普通get、post请求完后处理。
可以使用mina框架做长连接的事情
(参考)http://fulerbakesi.iteye.com/blog/1592209
一般的,aidl常用于远程命令,远程获取数据,但是有时也需要远程调用并不定时回调,此时需要两个aidl(接口)文件:一个是调用接口,一个是回调接口
注册回调:
/**
* service的回调方法
*/
private ICallback.Stub mCallback = new ICallback.Stub() {
@Override
public void showResult(int result) {
Log.d(TAG, " result : " + result);
}
};
/**
* 注册connection
*/
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected");
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected");
mService = IService.Stub.asInterface(service);
try {
mService.registerCallback(mCallback);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
}
};
注册一个回调:
private RemoteCallbackList<icallback> mCallbacks = new RemoteCallbackList<icallback>();
private IService.Stub mBinder = new IService.Stub() {
@Override
public void unregisterCallback(ICallback cb){
if(cb != null) {
mCallbacks.unregister(cb);
}
}
@Override
public void registerCallback(ICallback cb){
if(cb != null) {
mCallbacks.register(cb);
}
}
};
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return mBinder;
}