长连接服务器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; }