package com.uas.standard_esop.util; import android.os.Handler; import android.util.Log; import com.uas.standard_esop.util.tcp.SocketConfig; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.Socket; /** * Created by cjh-sail on 2022-11-25 */ public class QpushClient implements Runnable { protected static QpushClient mInstance; protected Handler mHandler; protected InetSocketAddress mAddress; protected String TAG = "QpushClient"; private final int TIME_OUT = 5 * 1000; //巡检周期 private final int CHECK_PERIOD = 2 * 1000; //连接尝试间隔时间 private final int CONNECT_PERIOD = 30 * 1000; private final int HEARTBEART_PERIOD = 10 * 1000; //若连接失败或响应失败,则尝试次数为9,若仍无效,则不再尝试 private final int CONNECT_TRY_TIMES = 9; //连接尝试次数 private int mConnectCount; private static Socket mClientSocket; String mHost; int mPort; //设置是否去读取数据 boolean isStartRecieveMsg = false; //开启心跳检测 boolean isKeepHeartBeat = false; private QpushClient(Handler handler) { mHandler = handler; } public static QpushClient getInstance(Handler handler) { if (mInstance == null) { mInstance = new QpushClient(handler); } return mInstance; } public void init(String host, int port) { mHost = host; mPort = port; new Thread(this).start(); } @Override public void run() { mAddress = new InetSocketAddress(mHost, mPort); if (mClientSocket == null) { mClientSocket = new Socket(); } //尝试连接,若未连接,则设置尝试次数 // while (!mClientSocket.isConnected() && mConnectCount < CONNECT_TRY_TIMES) { // connect(); // if (!mClientSocket.isConnected()) { // mConnectCount++; // sleep(CONNECT_PERIOD); // // } else { // mConnectCount = 0;//连接上,则恢复置0 // } // } // sendMsg("111"); if (!mClientSocket.isConnected()||mClientSocket==null){ connect(); return; } if (mClientSocket.isConnected()) { isStartRecieveMsg = true; isKeepHeartBeat = true; Log.e("mClinentSockets1=====",mClientSocket.isConnected()+""); //开始登陆 // sendMsg("login"); recvMsg(2); keepHeartBeat(); }else { connect(); recvMsg(1); } } public static boolean isTcpConnectionSuccessful(String host, int port) { try { mClientSocket = new Socket(host, port); mClientSocket.close(); // 立即关闭连接 return true; } catch (Exception e) { return false; } } private void connect() { try { mClientSocket.connect(mAddress); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "mClientSocket.connect fail " + e.getMessage()); if (e.getMessage().equals("Socket closed")){ onDestory(); recvMsg(1); } } } /** * 心跳维护 */ private void keepHeartBeat() { //设置心跳频率,启动心跳 while(isKeepHeartBeat){ // sendMsg("我是心跳包"); sleep(HEARTBEART_PERIOD); } } BufferedWriter mWriter; BufferedReader mReader; /** * 不断的检测是否有服务器推送的数据过来 */ public void recvMsg(int ports) { if (ports==1){ isStartRecieveMsg=false; return; } // while (mClientSocket != null && mClientSocket.isConnected() && !mClientSocket.isClosed()) { try { mReader = new BufferedReader(new InputStreamReader(mClientSocket.getInputStream(), SocketConfig.GBK)); // while (isStartRecieveMsg) { if (mReader.ready()) { /*读取一行字符串,读取的内容来自于客户机 reader.readLine()方法是一个阻塞方法, 从调用这个方法开始,该线程会一直处于阻塞状态, 直到接收到新的消息,代码才会往下走*/ // String data = mReader.readLine(); char[] getData = new char[9999999]; // mReader.read(getData, 0, getData.length); int count = 0; // String data = String.valueOf(getData); //handler发送消息,在handleMessage()方法中接收 // UTF-8:JAVAN寰堝睂ÌÆkѷ㱾拌w��Ꙙ@ 先转码,再去除不可见字符 // String replaceAllRds = data.replaceAll("�", ""); // Log.e("data=====",data); StringBuffer sb = new StringBuffer(); while ((count = mReader.read(getData,0,getData.length))>=-1) { sb.append(getData,0, count); break; } String datas = sb.toString(); handlerMsg(datas); // onDestory(); // return; Thread.sleep(5000); onDestory(); } // mClientSocket.setReuseAddress(true); } catch (Exception ex) { ex.printStackTrace(); } // sleep(200); // } // if (!mClientSocket.isConnected()) { // try { // mClientSocket.setReuseAddress(true); // connect(); // recvMsg(1); // } catch (SocketException e) { // e.printStackTrace(); // } // // } // sleep(CHECK_PERIOD); } private void sleep(long sleepTime) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 销毁socket */ public void onDestory() { if (mClientSocket != null) { try { mClientSocket.close(); recvMsg(1); } catch (IOException e) { e.printStackTrace(); } mClientSocket = null; } } /** * 发送 * @param message */ public void sendMsg(String message) { PrintWriter writer; try { if (mClientSocket.getOutputStream()==null){ return; } writer = new PrintWriter(new OutputStreamWriter( mClientSocket.getOutputStream()), true); writer.println(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * Ready for use. */ public void close() { try { if (mClientSocket != null && !mClientSocket.isClosed()) mClientSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 处理服务器返回过来的消息 * @param data */ private void handlerMsg(String data){ //对数据进行protobuf解析 //消息类型:1=登录成功、2=心跳检测、3=推送消息 int msgType=3; switch(msgType){ case 1: sendMsg("success"); break; case 2: sendMsg("error"); break; case 3: //需要通知service // sendMsg("success"); mHandler.obtainMessage(1, data).sendToTarget(); break; } } }