hxb
2021-12-21 8b66be08179b026cb0e601733dacd43de97e5b01
完善下网关上网重连功能及广播设备基本数据
1个文件已添加
12个文件已修改
760 ■■■■■ 已修改文件
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLLink.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/AuthenticateRequest.java 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/BroadcastRequest.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java 286 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -82,7 +82,7 @@
        rv.setLayoutManager(new LinearLayoutManager(this));
        checkIfCertified();
        initDeviceInfo();
        registerAllTopicsListener();
        ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
@@ -202,6 +202,7 @@
            @Override
            public void onMessage(Object msg) {
                LinkResponse response = (LinkResponse) msg;
                handleLinkResponse(response);
            }
        };
        HDLLink.getInstance().registerAllTopicsListener(allTopicsListener);
@@ -250,6 +251,23 @@
        HDLLink.getInstance().removeAllTopicsListener(allTopicsListener);
    }
    void initDeviceInfo()
    {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("123456789");
        infoBean.setIPMAC("12345678900");
        infoBean.setDeviceName("音乐播放器");//设备名字
        infoBean.setDeviceModel("MCLog.431");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.88.1");
        infoBean.setIPAddress(IpUtils.getIP(this));
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE08");
        infoBean.setSid("010105000000FE08110100000000");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    /**
     * 入网认证
     */
HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/config/TopicConstant.java
@@ -77,4 +77,14 @@
    //8.6场景删除
    public static final String SCENE_DELETE = "/user/%s/custom/scene/delete";
    /**
     * 设备连接TCP之前广播
     */
    public static final String BROADCAST="/user/all/custom/gateway/broadcast";
    /**
     * 主网关回复
     */
    public static final String BROADCAST_REPLY="/user/all/custom/gateway/broadcast_reply";
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/HDLLink.java
@@ -177,14 +177,25 @@
    }
    /**
     * 通用UDP广播发送指令
     * 通用UDP发送指令
     * 1秒没响应就让他重新发送,重试3次
     * @param topic 发送数据
     * @param bodyStr body内容
     * @param callBack 回调
     */
    public void udpSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr, callBack);
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,false, callBack);
    }
    /**
     * 通用广播UDP发送指令
     * 1秒没响应就让他重新发送,重试3次
     * @param topic 发送数据
     * @param bodyStr body内容
     * @param callBack 回调
     */
    public void udpBroadcastSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,true, callBack);
    }
    /**
@@ -206,7 +217,17 @@
     * @param bodyStr  回复的主题
     */
    public void udpSendMsg(String topic, String bodyStr) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr);
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,false);
    }
    /**
     * 通用广播发送指令 只发一次,不监听回复,不重发
     *
     * @param topic    发送数据
     * @param bodyStr  回复的主题
     */
    public void udpBroadcastSendMsg(String topic, String bodyStr) {
        HDLAuthSocket.getInstance().udpSendMsg(topic, bodyStr,true);
    }
    /**
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/AuthenticateRequest.java
@@ -97,46 +97,197 @@
        private String ip_gateway;
        private String dns1 = "114.114.114.114";
        private String dns2 = "8.8.8.8";
        private VersionBean[] versions;
        private String gateway_type;
        private String hw_version;
        private String fw_version;
        public String getOID() { return oid; }
        /**
         * 设备Oid
         * @param value
         */
        public void setOID(String value) { this.oid = value; }
        public String getDeviceMAC() { return device_mac; }
        /**
         * 设备Mac
         * @param value
         */
        public void setDeviceMAC(String value) { this.device_mac = value; }
        /**
         * 设备名
         * @return
         */
        public String getDeviceName() { return device_name; }
        /**
         * 设备名
         * @param value
         */
        public void setDeviceName(String value) { this.device_name = value; }
        /**
         * 设备型号
         * @return
         */
        public String getDeviceModel() { return device_model; }
        /**
         * 设备型号
         * @param value
         */
        public void setDeviceModel(String value) { this.device_model = value; }
        /**
         * 连接类型,有线还是无线
         * @return
         */
        public String getAccessMode() { return access_mode; }
        /**
         * 连接类型,有线还是无线
         * @param value
         */
        public void setAccessMode(String value) { this.access_mode = value; }
        /**
         * 设备sid
         * @return
         */
        public String getSid() { return sid; }
        /**
         * 设备sid
         * @param value
         */
        public void setSid(String value) { this.sid = value; }
        /**
         * 设备IPMAC
         * @return
         */
        public String getIPMAC() { return ip_mac; }
        /**
         * 设备IPMAC
         * @param value
         */
        public void setIPMAC(String value) { this.ip_mac = value; }
        /**
         * 设备IP地址
         * @return
         */
        public String getIPAddress() { return ip_address; }
        /**
         * 设备IP地址
         * @param value
         */
        public void setIPAddress(String value) { this.ip_address = value; }
        /**
         * 子网掩码
         * @return
         */
        public String getNetmask() { return netmask; }
        /**
         * 子网掩码
         * @param value
         */
        public void setNetmask(String value) { this.netmask = value; }
        /**
         * 网关IP
         * @return
         */
        public String getIPGateway() { return ip_gateway; }
        /**
         * 网关IP
         * @param value
         */
        public void setIPGateway(String value) { this.ip_gateway = value; }
        /**
         * DNS1
         * @return
         */
        public String getDns1() { return dns1; }
        /**
         * DNS1
         * @param value
         */
        public void setDns1(String value) { this.dns1 = value; }
        /**
         * DNS2
         * @return
         */
        public String getDns2() { return dns2; }
        /**
         * DNS2
         * @param value
         */
        public void setDns2(String value) { this.dns2 = value; }
        public VersionBean[] getVersions() { return versions; }
        public void setVersions(VersionBean[] value) { this.versions = value; }
        public VersionBean[] getVersions() {return null;  }
        public void setVersions(VersionBean[] value) {  }
        /**
         * 网关类型
         * @return
         */
        public String getGateway_type() {
            return gateway_type;
        }
        /**
         * 网关类型
         * @param gateway_type
         */
        public void setGateway_type(String gateway_type) {
            this.gateway_type = gateway_type;
        }
        /**
         * 硬件版本
         * @return
         */
        public String getHw_version() {
            return hw_version;
        }
        /**
         *硬件版本
         * @param
         */
        public void setHw_version(String hw_version) {
            this.hw_version = hw_version;
        }
        /**
         * 固件版本
         * @return
         */
        public String getFw_version() {
            return fw_version;
        }
        /**
         * 固件版本
         * @param fw_version
         */
        public void setFw_version(String fw_version) {
            this.fw_version = fw_version;
        }
    }
    public static class VersionBean implements Serializable{
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/bean/request/BroadcastRequest.java
New file
@@ -0,0 +1,54 @@
package com.hdl.sdk.connect.bean.request;
import java.io.Serializable;
/**
 * Created by jlchen on 11/11/21.
 *
 * /user/all/custom/gateway/broadcast
 */
public class BroadcastRequest implements Serializable {
    private String id;
    private String time_stamp;
    private AuthenticateRequest.AuthenticateDeviceInfoBean objects;//当前设备基本信息
    private String code;//
    public BroadcastRequest(String id, String time_stamp, AuthenticateRequest.AuthenticateDeviceInfoBean objects, String code) {
        this.id = id;
        this.time_stamp = time_stamp;
        this.objects = objects;
        this.code = code;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getTime_stamp() {
        return time_stamp;
    }
    public void setTime_stamp(String time_stamp) {
        this.time_stamp = time_stamp;
    }
    public AuthenticateRequest.AuthenticateDeviceInfoBean getObjects() {
        return objects;
    }
    public void setObjects(AuthenticateRequest.AuthenticateDeviceInfoBean objects) {
        this.objects = objects;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/config/HDLLinkConfig.java
@@ -4,6 +4,7 @@
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.utils.SPUtils;
import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
@@ -23,6 +24,8 @@
    private String ipAddress;
    private boolean isLocalEncrypt;//网关是否需要加密通讯
    private GatewaySearchBean currentGateway;//当前网关
    private AuthenticateRequest.AuthenticateDeviceInfoBean deviceInfoBean;//当前设备基本信息
    /**
     * instance
@@ -160,6 +163,7 @@
        return (!topicStr.contains(TopicConstant.GATEWAY_AUTH_BROADCAST) //网关广播入网指令
                && !topicStr.contains(TopicConstant.DEIVCE_AUTH_REQUEST) //入网认证
                && !topicStr.contains(TopicConstant.GATEWAY_SEARCH) //搜索网关主题
                && !topicStr.equals(TopicConstant.BROADCAST)
                && isLocalEncrypt//启用加密标志
        );
    }
@@ -174,4 +178,11 @@
        return String.format(topicStr, gatewayId);
    }
    public AuthenticateRequest.AuthenticateDeviceInfoBean getDeviceInfoBean() {
        return deviceInfoBean;
    }
    public void setDeviceInfoBean(AuthenticateRequest.AuthenticateDeviceInfoBean deviceInfoBean) {
        this.deviceInfoBean = deviceInfoBean;
    }
}
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java
@@ -359,9 +359,10 @@
     *
     * @param topic    发送数据
     * @param bodyStr  回复的主题
     * @param broadcast 是否要广播
     * @param callBack 回调
     */
    public void udpSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) {
    public void udpSendMsg(String topic, String bodyStr,boolean broadcast,  HDLLinkResponseCallBack callBack) {
        if (TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) {
            if (callBack != null) {
                callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR));
@@ -378,6 +379,9 @@
        LinkRequest message = new LinkRequest(topic, bodyStr);
        String ip = HDLLinkConfig.getInstance().getIpAddress();
        if(broadcast) {
            ip = IpUtils.getBroadcastAddress();
        }
        HdlSocketHelper.sendUdp(getUdpBoot(), ip, UDP_PORT, message, new HdlSocketHelper.HdlSocketListener() {
                    @Override
                    public void onSucceed(Object msg) {
@@ -399,8 +403,9 @@
     *
     * @param topic   发送数据
     * @param bodyStr 回复的主题
     * @param broadcast 是否广播
     */
    public void udpSendMsg(String topic, String bodyStr) {
    public void udpSendMsg(String topic, String bodyStr,boolean broadcast) {
        if (TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) {
            LogUtils.e("udpSendMsg", "参数不能为空");
            return;
@@ -410,7 +415,10 @@
            return;
        }
        LinkRequest message = new LinkRequest(topic, bodyStr);
        String ip = HDLLinkConfig.getInstance().getIpAddress();// IpUtils.getBroadcastAddress();
        String ip = HDLLinkConfig.getInstance().getIpAddress();
        if(broadcast) {
            ip = IpUtils.getBroadcastAddress();
        }
        HdlSocketHelper.sendUdpOne(getUdpBoot(), ip, UDP_PORT, message);
    }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java
@@ -3,40 +3,34 @@
import android.text.TextUtils;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.event.EventDispatcher;
import com.hdl.sdk.common.event.EventListener;
import com.hdl.sdk.common.exception.HDLLinkCode;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.IdUtils;
import com.hdl.sdk.common.utils.IpUtils;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.SPUtils;
import com.hdl.sdk.common.utils.ThreadToolUtils;
import com.hdl.sdk.common.utils.gson.GsonConvert;
import com.hdl.sdk.connect.bean.request.BroadcastRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalResponse;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.request.FunctionAttributeRequest;
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
import com.hdl.sdk.connect.bean.LinkRequest;
import com.hdl.sdk.connect.bean.LinkResponse;
import com.hdl.sdk.connect.bean.request.PropertyReadRequest;
import com.hdl.sdk.connect.bean.request.PropertyUpRequest;
import com.hdl.sdk.connect.callback.BaseCallBack;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack;
import com.hdl.sdk.connect.config.HDLLinkConfig;
import com.hdl.sdk.connect.protocol.LinkMessageDecoder;
import com.hdl.sdk.connect.protocol.LinkMessageEncoder;
import com.hdl.sdk.socket.SocketBoot;
import com.hdl.sdk.socket.SocketOptions;
import com.hdl.sdk.socket.client.TcpClient;
import com.hdl.sdk.socket.client.UdpClient;
import com.hdl.sdk.socket.codec.MessagePipeLine;
import com.hdl.sdk.socket.listener.ConnectStatusListener;
import com.hdl.sdk.socket.listener.SendListener;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
@@ -63,7 +57,7 @@
        statusListener = new ConnectStatusListener() {
            @Override
            public void onConnecting() {
                broadcastRequest();
            }
            @Override
@@ -78,6 +72,29 @@
        };
    }
    /**
     * 广播自身信息给主网关
     */
    private void broadcastRequest() {
        String time = String.valueOf(System.currentTimeMillis());
        if (null == HDLLinkConfig.getInstance().getDeviceInfoBean()) {
            LogUtils.i("DeviceInfoBean为空,请设置当前对象");
            return;
        }
        BroadcastRequest request = new BroadcastRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), "200");
        HDLAuthSocket.getInstance().udpSendMsg("/user/all/custom/gateway/broadcast", GsonConvert.getGson().toJson(request), true, new HDLLinkResponseCallBack() {
            @Override
            public void onSuccess(LinkResponse msg) {
                LogUtils.i("广播信息给主网关成功!");
            }
            @Override
            public void onError(HDLLinkException e) {
            }
        });
    }
    private static class SingletonInstance {
        private static final HDLSocket INSTANCE = new HDLSocket();
    }
@@ -86,17 +103,17 @@
        return SingletonInstance.INSTANCE;
    }
    SocketOptions options;
    private SocketOptions getTcpOptions() {
        final SocketOptions options = new SocketOptions();
        if(null!=options){
            return options;
        }
        options = new SocketOptions();
        final MessagePipeLine pipeLine = new MessagePipeLine();
        pipeLine.add(new LinkMessageDecoder());
        pipeLine.add(new LinkMessageEncoder());
        options.setHandleMessage(pipeLine);
        options.setEnabledHeartbeat(false);//是否开启心跳包发送检测
//        options.setHeartbeatTimeInterval(10*1000L);
//        options.setHeartbeatData("TCP");
//        options.setEnabledHeartbeat(true);//是否开启心跳包发送检测
        options.addConnectStatusListener(statusListener);
        return options;
    }
@@ -389,9 +406,11 @@
        if (TextUtils.isEmpty(getTcpIp())) {
            throw new RuntimeException("请搜索网关");
        }
        if (tcpBoot == null) {
        //如果没有初始化,或者网关IP更改了,就重新初始化
        if (tcpBoot == null||!getTcpOptions().getIp().equals(getTcpIp())) {
            tcpBoot = TcpClient.init(getTcpIp(), getTcpPort(), getTcpOptions());
        }
        return tcpBoot;
    }
HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java
@@ -21,7 +21,7 @@
 */
public class HdlSocketHelper {
    private static final Long DEF_SEND_TIMEOUT = 1000L;
    private static final Long DEF_SEND_TIMEOUT = 500L;
    private static final int DEF_MAX_RETRY = 4;
    private static final int DEF_SEND_ONE = 1;
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketBoot.java
@@ -27,25 +27,19 @@
public class SocketBoot {
    private ExecutorService connectThread;
    private ScheduledExecutorService heartbeatThread;
    private ExecutorService sendThread;
    private ExecutorService receiveThread;
    private ScheduledExecutorService delayThread;
    private final IClient client;
    /**
     * tcp是否已经连接
     */
    private boolean connected=false;
    public IClient getClient() {
        return client;
    }
    /**
     * socket是否在运行
     */
    private final AtomicBoolean isRun = new AtomicBoolean(false);
    private final AtomicBoolean isOpenRetry = new AtomicBoolean(false);
    private final AtomicInteger resendCount = new AtomicInteger(0);
    private final BlockingQueue<SocketRequest> mMessageQueue = new LinkedBlockingDeque<>();
@@ -53,88 +47,42 @@
    public SocketBoot(IClient client) {
        this.client = client;
        initConnectThread();
        initReceiveThread();
        initSendThread();
    }
    public ScheduledExecutorService getHeartBeat() {
        if (heartbeatThread == null) {
            heartbeatThread = ThreadToolUtils.getInstance().newScheduledThreadPool(1);
        }
        return heartbeatThread;
    }
    public void connect() {
        resendCount.set(0);
        resetConnect(true);
        isOpenRetry.set(true);
    }
    public synchronized void resetConnect(boolean isFirst) {
        final int maxRetry = client.getOptions().getMaxRetry();
        if (maxRetry == 0 && resendCount.get() > 0 ||
                (maxRetry > 0 && maxRetry + 1 < resendCount.get())) {
            LogUtils.d("====", "===重连次数达到最大==");
            return;
        }
        if (!client.isConnect()) {
            if (connectThread == null) {
                connectThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
            }
            connectThread.execute(new Runnable() {
                @Override
                public void run() {
                    client.onConnectStatus(ConnectStatus.CONNECTING);
                    if (!isFirst) {
                        try {
                            resendCount.set(resendCount.get() + 1);
                            Thread.sleep(300L);
                            LogUtils.d("====", "==重连第" + resendCount + "次==");
                        } catch (Exception ignored) {
                        }
                    }
                    try {
                        client.connect();
                        isRun.set(true);
                        if (client.isConnect()) {
                            LogUtils.d("====", "====连接成功====");
                            startHeartbeat();
                            initSendThread();
                            initReceiveThread();
                            client.onConnectStatus(ConnectStatus.CONNECTED);
                            resendCount.set(0);
                        } else {
                            throw new ConnectException();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        LogUtils.d("====", "===连接失败===" + e);
                        //再判断一下有没有连接
                        if (!client.isConnect()) {
                            isRun.set(false);
                            client.onConnectStatus(ConnectStatus.DISCONNECT);
                            stopHeartbeat();
                            disconnectError();
                        }
                    }
                }
            });
    /**
     * 连接tcp,内部维护掉,可以不用开放外部,根据这个业务我特性处理好
     */
    private synchronized void connect() {
        try {
            LogUtils.i("TCP连接");
            client.onConnectStatus(ConnectStatus.CONNECTING);
            Thread.sleep(1500);
            client.connect();
            connected=true;
            client.onConnectStatus(ConnectStatus.CONNECTED);
        }catch(Exception e) {
            LogUtils.e(e.getMessage());
        }
    }
    public void initSendThread() {
    /**
     * 初始化发送线程,只需要初始化一次
     */
    private void initSendThread() {
        if (sendThread == null) {
            sendThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
        }
        sendThread.execute(new Runnable() {
            @Override
            public void run() {
                while (isRun.get()) {
                    if (client.isConnect()) {
            sendThread.execute(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            SocketRequest socketRequest = mMessageQueue.take();
                            final String sendStr = new String(socketRequest.getData(), 0, socketRequest.getData().length);
                            LogUtils.i("发送数据:"+sendStr);
                            LogUtils.i("发送数据:" + sendStr);
                            final String action = socketRequest.getAction();
                            try {
                                client.sendMsg(socketRequest.getData());
@@ -145,33 +93,22 @@
                                    }
                                }
                            } catch (Exception e) {
                                connected = false;
                                LogUtils.e("发送失败:" + e.getMessage());
                                if (!TextUtils.isEmpty(action)) {
                                    SendListener sendListener = sendMap.get(action);
                                    if (sendListener != null) {
                                        sendListener.onError();
                                    }
                                }
                                stopHeartbeat();
                                if (sendThread != null) {
                                    sendThread.shutdownNow();
                                }
                                if (isRun.get()) {
                                    disconnectError();
                                }
                            }
                        } catch (InterruptedException ignored) {
                        } catch (Exception e) {
                        }
                    }
                }
                LogUtils.d("=====", "==发送线程关闭==");
            }
        });
            });
        }
    }
    /**
@@ -183,151 +120,94 @@
            receiveThread.execute(new Runnable() {
                @Override
                public void run() {
                    while (isRun.get()) {
                        if (client.isConnect()) {
                            try {
                    while (true) {
                        try {
                            if (connected) {
                                //读取数据
                                client.onHandleResponse();
                            } catch (Exception e) {
                                e.printStackTrace();
                                disconnectError();
                            } else {
                                try {
                                    Thread.sleep(1000);
                                } catch (Exception ee) {
                                }
                            }
                        } catch (Exception e) {
                            connected = false;
                            LogUtils.e("接收数据线程异常" + e.getMessage());
                        }
                    }
                    LogUtils.i("Socket 线程退出接收数据");
                }
            });
        }
    }
    /**
     * 初始化重新连接线程
     */
    private void initConnectThread() {
        if (connectThread == null) {
            connectThread = ThreadToolUtils.getInstance().newFixedThreadPool(1);
            //一定时间检测一次连接情况,没有连接就执行连接,连接统一由这里维护
            connectThread.execute(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            if (!connected) {
                                reconect();
                            }
                            Thread.sleep(10*1000);
                        } catch (Exception e) {
    public void startHeartbeat() {
        if (heartbeatThread != null) {
            heartbeatThread.shutdownNow();
            heartbeatThread = null;
        }
        if (client.getOptions() == null || client.getOptions().getHeartbeatTimeInterval() <= 0 || !client.getOptions().isEnabledHeartbeat()) {
            return;
        }
        getHeartBeat().scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                if (isRun.get()) {
//                    LogUtils.d("====", "===发送心跳包===");
                    if (client.getOptions() != null) {
                        final byte[] heartBeat = client.getOptions().getHeartbeatData();
                        if (heartBeat != null) {
                            sendMsg(heartBeat, false, null);
                        } else {
                            sendMsg(new byte[0], false, null);
                        }
                    }
                }
            }
        }, client.getOptions().getHeartbeatTimeInterval(), client.getOptions().getHeartbeatTimeInterval(), TimeUnit.MILLISECONDS);
    }
    public void stopHeartbeat() {
        if (heartbeatThread != null) {
            heartbeatThread.shutdownNow();
            heartbeatThread = null;
            });
        }
    }
    /**
     * 重新连接
     */
    private void reconect() {
        disconnect();
        connect();
    }
    /**
     * 发送无需回调
     * @param msg 发送的数据
     */
    public void sendMsg(byte[] msg) {
        sendMsg(msg, true, null);
        sendMsg(msg, null);
    }
    public void sendMsg(byte[] msg, SendListener listener) {
        sendMsg(msg, true, listener);
    }
    /**
     * @param listener 一般情况无需监听
     */
    private void sendMsg(byte[] msg, boolean isRefreshRetry, SendListener listener) {
        if (isRefreshRetry) {
            //重置连接次数
            resendCount.set(0);
        }
    public void sendMsg(byte[] msg, SendListener listener) {
        try {
            SocketRequest request = new SocketRequest(msg);
            if (listener != null && !TextUtils.isEmpty(request.getAction())) {
                sendMap.put(request.getAction(), listener);
            }
            mMessageQueue.put(request);
        } catch (InterruptedException ignored) {
        } catch (Exception e) {
        }
        if (!client.isConnect()) {
            resetConnect(false);
        }
    }
    /**
     * 发生错误,重连
     * 关闭连接
     */
    private void disconnectError() {
        disconnect();
        isRun.set(false);
        if (isOpenRetry.get()) {
            if (delayThread != null) {
                delayThread.shutdownNow();
            }
            delayThread = ThreadToolUtils.getInstance().newScheduledThreadPool(1);
            delayThread.schedule(new Runnable() {
                @Override
                public void run() {
                    if (!client.isConnect() && isOpenRetry.get()) {
                        resetConnect(false);
                    }
                }
            }, 3000, TimeUnit.MILLISECONDS);
        }
    }
    private synchronized void disconnect() {
        if (client.isConnect()) {
        try {
            client.disconnect();
            //断开连接
            client.onConnectStatus(ConnectStatus.DISCONNECT);
        }
    }
        } catch (Exception e) {
    public synchronized void close() {
        isOpenRetry.set(false);
        isRun.set(false);
        if (connectThread != null) {
            connectThread.shutdownNow();
            connectThread = null;
        }
        if (heartbeatThread != null) {
            heartbeatThread.shutdownNow();
            heartbeatThread = null;
        }
        if (sendThread != null) {
            sendThread.shutdownNow();
            sendThread = null;
        }
        if (receiveThread != null) {
            receiveThread.shutdownNow();
            receiveThread = null;
        }
        sendMap.clear();
        client.disconnect();
        mMessageQueue.clear();
    }
    public synchronized void release() {
        close();
        if (client != null && client.getOptions() != null) {
            client.getOptions().clearConnectStatusListener();
        }
    }
    public boolean isConnect() {
        return client.isConnect();
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/SocketOptions.java
@@ -15,19 +15,8 @@
public class SocketOptions {
    //发送目标地址IP
    private String ip;
    //设置读取缓存
    private int readMaxBufferSize = 512;
    //发送心跳包
    private boolean isEnabledHeartbeat = true;
    //心跳包
    private byte[] heartbeatData;
    //心跳包时间间隔
    private long heartbeatTimeInterval = 300L;
    private String ip="";
    private int port;
    //处理数据
    private IHandleMessage handleMessage;
@@ -35,21 +24,17 @@
    //监听状态
    private List<ConnectStatusListener> mConnectStatusListener;
    //最大重连次数,小于0无限次数,等于0不重连
    private int maxRetry = -1;
    private boolean isTcpNoDelay;
    private boolean isReuseAddress;
    //保持活动状态
    private boolean isKeepAlive;
    private boolean isOOBInline;
    private int sendBufferSize;
    private int receiveBufferSize;
    private int soTimeout;
    private boolean soLinger;
    public String getIp() {
        return ip;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public void setIp(String ip) {
@@ -62,38 +47,6 @@
    public void setHandleMessage(IHandleMessage handleMessage) {
        this.handleMessage = handleMessage;
    }
    public boolean isEnabledHeartbeat() {
        return isEnabledHeartbeat;
    }
    public void setEnabledHeartbeat(boolean enabledHeartbeat) {
        isEnabledHeartbeat = enabledHeartbeat;
    }
    public byte[] getHeartbeatData() {
        return heartbeatData;
    }
    public void setHeartbeatData(byte[] heartbeatData) {
        this.heartbeatData = heartbeatData;
    }
    public void setHeartbeatData(String heartbeatData) {
        try {
            this.heartbeatData = heartbeatData.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    public long getHeartbeatTimeInterval() {
        return heartbeatTimeInterval;
    }
    public void setHeartbeatTimeInterval(long heartbeatTimeInterval) {
        this.heartbeatTimeInterval = heartbeatTimeInterval;
    }
    public void clearConnectStatusListener() {
@@ -115,26 +68,8 @@
        }
    }
    public List<ConnectStatusListener> getConnectStatusListener() {
        return mConnectStatusListener;
    }
    public int getMaxRetry() {
        return maxRetry;
    }
    public void setMaxRetry(int maxRetry) {
        this.maxRetry = maxRetry;
    }
    public int getReadMaxBufferSize() {
        return readMaxBufferSize;
    }
    public void setReadMaxBufferSize(int readMaxBufferSize) {
        this.readMaxBufferSize = readMaxBufferSize;
    }
}
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/IClient.java
@@ -12,11 +12,6 @@
    void disconnect();
    /**
     * 是否已经连接
     */
    boolean isConnect();
    SocketOptions getOptions();
HDLSDK/hdl-socket/src/main/java/com/hdl/sdk/socket/client/TcpClient.java
@@ -15,6 +15,7 @@
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
@@ -31,12 +32,32 @@
    private Socket mSocket;
    private byte[] readBuffer;
    private final static List<TcpClient> tcpClientList = new ArrayList();
    /**
     * 从连接池中找出当前IP及端口的连接客户端
     * @param ipAdderss 连接IP地址
     * @param port 连接端口
     * @return
     */
    public static TcpClient getTcpClientByIP(String ipAdderss,int port) {
        for(TcpClient tcpClient:tcpClientList){
            if(tcpClient.ip.equals(ipAdderss)&&tcpClient.port==port)
            {
                return tcpClient;
            }
        }
        return  null;
    }
    private byte[] readBuffer = new byte[4*1024];
    private TcpClient(String ip, int port, SocketOptions socketOptions) {
        this.socketOptions = socketOptions;
        this.ip = ip;
        this.port = port;
        socketOptions.setIp(ip);
        socketOptions.setPort(port);
    }
    public static SocketBoot init(String ip, int port, SocketOptions options) {
@@ -52,8 +73,11 @@
        mSocket.setTcpNoDelay(true);
        mSocket.setReuseAddress(true);
        mSocket.setKeepAlive(true);
        readBuffer = new byte[options.getReadMaxBufferSize()];
        tcpClientList.add(this);
    }
    @Override
@@ -66,16 +90,6 @@
            }
        }
    }
    @Override
    public boolean isConnect() {
        if (mSocket == null) {
            return false;
        }
        return mSocket.isConnected() && !mSocket.isClosed();
    }
    @Override
    public synchronized SocketOptions getOptions() {