做项目过程中,遇到Socket长连接,以及客户端断掉之后重连等问题。
/* * 缓存队列处理线程 * 1、建立socket长连接 * 2、消费缓存队列数据发给logAgent * 3、断点自动重连 * **/
public class DataProcessClient { private String serverIp; private int port; private Socket socket; private DataOutputStream outputStream; private SocketReadThread socketReadThread; private HeartbeatThread heartbeatThread; private Boolean isRelease = false; private static final long HEART_BEAT_RARE = 4 * 1000; private long sendTime = 0L; static public final String AGENT_SERVER = "agent.server"; static public final String SERVER_PORT = "agent.server.port"; public DataProcessClient(){ this.serverIp = "127.0.0.1"; this.port = 29888; } static private String getAgentServer(){ return PropertiesManager.getProperty(AGENT_SERVER); } static private int getPort(){ return Integer.valueOf(PropertiesManager.getProperty(SERVER_PORT)); } public void connectToServer() { try { this.socket = new Socket(); this.socket.connect(new InetSocketAddress(serverIp,port)); this.outputStream = new DataOutputStream(socket.getOutputStream()); //读取服务器数据线程 this.socketReadThread = new SocketReadThread(); this.socketReadThread.start(); //心跳检测 if(!isRelease){ this.heartbeatThread = new HeartbeatThread(); this.heartbeatThread.start(); } } catch (IOException e) { e.printStackTrace(); } } public void append(String log) { System.out.println("DataProcess append start"); try { //异步方式 DataOutputStream bos = this.outputStream; if(bos != null){ byte[] bytes = log.getBytes("utf-8"); int len = bytes.length; bos.write(bytes, 0, len); bos.flush(); } } catch (Exception e) { e.printStackTrace(); } } /* * 释放socket * **/ private void releaseLastSocket() { try{ if(socket !=null){ if(!socket.isClosed()){ socket.close(); } } socket = null; }catch(Exception e){ e.printStackTrace(); } } /* * 心跳线程 * * **/ private class HeartbeatThread extends Thread { @Override public void run() { while(true){ if(System.currentTimeMillis() - sendTime >= HEART_BEAT_RARE){ boolean isSuccess = sendHeartBeatMsg(""); if(!isSuccess){ TraceClients.selfLog("连接已断开正在重连......"); socketReadThread.release(); releaseLastSocket(); isRelease = true; connectToServer(); } } try { Thread.sleep(HEART_BEAT_RARE); } catch (InterruptedException e) { e.printStackTrace(); } } } private boolean sendHeartBeatMsg(String msg) { if(socket == null){ return false; } try { if(!socket.isClosed() && !socket.isOutputShutdown()){ String message = msg + "\r\n"; outputStream.write(message.getBytes()); outputStream.flush(); sendTime = System.currentTimeMillis(); }else{ return false; } } catch (IOException e) { e.printStackTrace(); return false; } return true; } } /* * 服务器数据读取线程 * **/ public class SocketReadThread extends Thread { private volatile boolean mStopThread = false; @Override public void run() { DataInputStream dataInputStream = null; try{ dataInputStream = new DataInputStream(socket.getInputStream()); TraceClients.selfLog("SocketReadThread running!"); while(!mStopThread){ String resultStr = dataInputStream.readUTF(); System.out.println("resultStr="+resultStr); handleResulrStr(resultStr); } }catch(Exception e){ e.printStackTrace(); }finally{ try{ socket.close(); if(dataInputStream != null){ dataInputStream.close(); } }catch(Exception e){ e.printStackTrace(); } } } private void handleResulrStr(String resultStr) { TraceClients.selfLog(resultStr); } public void release() { mStopThread = true; releaseLastSocket(); } } }