实现代码
public class QpushClient implements Runnable {
protected static QpushClient mInstance;
protected Handler mHandler;
protected InetSocketAddress mAddress;
String mIMEI;
protected String TAG = "QpushClient";
//socket连接的超时时间
private final int CONNECT_TIME_OUT = 5 * 1000;
//巡检周期
private final int CHECK_PERIOD = 2 * 1000;
//连接尝试间隔时间
private final int CONNECT_PERIOD = 30 * 1000;
private final int HEARTBEART_PERIOD = 30 * 1000;
//若连接失败或响应失败,则尝试次数为9,若仍无效,则不再尝试
private final int CONNECT_TRY_TIMES = 9;
private final int SEND_MSG_TYPE_HEARTBEAT = 1; //心跳包
private final int SEND_MSG_TYPE_SOCKET_LOGIN = 2; //发送socket登录包
//连接尝试次数
private int mConnectCount;
Socket mClientSocket;
String mHost;
int mPort;
//设置是否去读取数据
boolean isStartRecieveMsg = false;
//开启心跳检测
boolean isKeepHeartBeat = false;
BufferedReader mReader;
ScheduledExecutorService executor;//定位定时器
HeartBeatTask mHeartBeatTask;
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,String imei) {
mHost = host;
mPort = port;
mIMEI = imei;
new Thread(this).start();
isStartRecieveMsg = true;
isKeepHeartBeat = true;
}
@Override
public void run() {
mAddress = new InetSocketAddress(getIP(mHost), mPort);
//尝试连接,若未连接,则设置尝试次数
while (mConnectCount < CONNECT_TRY_TIMES) {
connect();
if (!mClientSocket.isConnected()) {
mConnectCount++;
sleep(CONNECT_PERIOD);
} else {
mConnectCount = 0;//连接上,则恢复置0
break;
}
}
if (mClientSocket.isConnected()) {
keepHeartBeat();
recvProtobufMsg();
// recvStringMsg();
}
}
private void connect() {
try {
if (mClientSocket == null) {
mClientSocket = new Socket();
}
mClientSocket.connect(mAddress, CONNECT_TIME_OUT);
Driver.HeartBeat heartbeat = Driver.HeartBeat.newBuilder().setImei(mIMEI).build();
Driver.ClientMessage socketLogin = Driver.ClientMessage.newBuilder().setType(1).setHeartBeat(heartbeat).build();
sendMsg(socketLogin,SEND_MSG_TYPE_SOCKET_LOGIN);
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "连接失败 mClientSocket.connect fail ,ip=" + mAddress.getHostName() + ";port=" + mAddress.getPort() + ";detail:" + e.getMessage());
}
}
/**
* 心跳维护
*/
private void keepHeartBeat() {
//设置心跳频率,启动心跳
if (isKeepHeartBeat) {
if (mHeartBeatTask == null) {
mHeartBeatTask = new HeartBeatTask();
}
try {
if (executor != null) {
executor.shutdownNow();
executor = null;
}
executor = Executors.newScheduledThreadPool(1);