nettyservice

package com.osanwen.nettydemo;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.content.LocalBroadcastManager;
asd
import com.google.gson.Gson;
import com.osanwen.nettydemo.bean.DescribeBean;
import com.osanwen.nettydemo.bean.FunctionBeanList;
import com.osanwen.nettydemo.coap.CoAP;
import com.osanwen.nettydemo.coap.DataParser;
import com.osanwen.nettydemo.coap.DataSerializer;
import com.osanwen.nettydemo.coap.DescribeReturn;
import com.osanwen.nettydemo.coap.EmptyMessage;
import com.osanwen.nettydemo.coap.FunctionReturn;
import com.osanwen.nettydemo.coap.Hello;
import com.osanwen.nettydemo.coap.Ping;
import com.osanwen.nettydemo.coap.VariableReturn;
import com.osanwen.nettydemo.utils.Encryptor;
import com.osanwen.nettydemo.utils.LogUtil;
import com.osanwen.nettydemo.utils.RSAUtils;
import com.osanwen.nettydemo.utils.Utils;
import com.osanwen.nettydemo.utils.VideoUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import timber.log.Timber;

/**
 * Created by LiuSaibao on 11/17/2016.
 */
public class NettyService extends Service implements NettyListener {

    private NetworkReceiver receiver;
    private static String sessionId = null;

    private ScheduledExecutorService mScheduledExecutorService;

    //关闭定时器
    private void shutdown() {
        if (mScheduledExecutorService != null) {
            mScheduledExecutorService.shutdown();
            mScheduledExecutorService = null;
        }
        counter = 1;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        receiver = new NetworkReceiver();
        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        NettyClient.getInstance().setListener(this);
        connect();
        return START_NOT_STICKY;
    }

    @Override
    public void onServiceStatusConnectChanged(int statusCode) {        //连接状态监听
        Timber.d("connect status:%d", statusCode);
        if (statusCode == NettyListener.STATUS_CONNECT_SUCCESS) {
            sendBrodcast(this, UPDATE_TXT_MES, "连接成功");

            LogUtil.v("loginHandler", "连接成功");
//            authenticData();
        } else {
            WriteLogUtil.writeLogByThread("tcp connect error");
            sendBrodcast(this, UPDATE_TXT_MES, "连接失败,取消心跳");
            LogUtil.v("LoginHandler", "连接失败");

            if(ifUseProducerAndConsumer) {
                consumer.stop();
                producer.stop();
            }

//            try {
//                Thread.sleep(5000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//          sendBrodcast(this, UPDATE_TXT_MES, "重新连接");

            //取消心跳
            shutdown();
        }
    }


    boolean ifUseProducerAndConsumer = true; //是否使用生产者消费模型 临时变量

    //生产者消费模型 start
    private final int TEMP_LEN = 1024 * 2; //缓存大小
    private byte[] tempBytes = new byte[TEMP_LEN];   //缓存
    private int writePos = 0; //读取的位置
    private int readPos = 0;  //写入的位置

    private class Producer implements Runnable {

        private BlockingQueue<EmptyMessage> queue;

        private boolean isRunning = true;

        public void stop() {
            isRunning = false;
        }

        public Producer(BlockingQueue<EmptyMessage> q) {
            this.queue = q;
        }

        @Override
        public void run() {
            //生产消息  定时检测缓存区里是否有完整的数据
            while (isRunning) {

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //当前要处理的消息的长度
                int msgLen = getTempbytesHeadLen();

                //判断消息是完整的
                int currentContentLen = writePos - readPos;

                if (currentContentLen < 0) {
                    currentContentLen += TEMP_LEN;
                }

                //如果当前缓存的内容的长度足够
                if (currentContentLen >= (msgLen + HEADLEN)) {

                    //解析消息并加入BlockingQueue中
                    byte[] contentBytes = new byte[msgLen];

//                    [0,10) readPos = 8    contentLen = 4;

                    if (((msgLen + HEADLEN) + readPos <= TEMP_LEN)) {  //数据全部在tempBytes的[readPos,readPos+currentContentLen)
                        System.arraycopy(tempBytes, readPos + HEADLEN, contentBytes, 0, msgLen);
                    } else {  //数据在tempBytes的[readPos,TEMP_LEN) 和 [0,(msgLen+HEADLEN)-(TEMP_LEN - readPos)) 两个区间

                        int tailLen = TEMP_LEN - readPos-HEADLEN; //8
                        int headLen = (msgLen) - tailLen; //8

                        System.arraycopy(tempBytes, readPos + HEADLEN, contentBytes, 0, tailLen); //复制尾部的数据
                        System.arraycopy(tempBytes, 0, contentBytes, tailLen, headLen);  //复制头部的数据
                    }

                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--contentBytes="+RSAUtils.bytesToHexString(contentBytes));

                    byte[] singleDecryptBytes = Encryptor.decrypt(Const.AES_KEY, Const.AES_IV_JIEMI, contentBytes);

                    if(singleDecryptBytes == null){
                        sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--解密失败");
                    }

                    //更新解密iv
                    System.arraycopy(contentBytes, 0, Const.AES_IV_JIEMI, 0, AES_IV_LEN);

                    //转化为emptyMessage对象
                    EmptyMessage msg = null;
                    try {
                        msg = dataParser.parseMessage(singleDecryptBytes);
                        sendBrodcast(NettyService.this, UPDATE_TXT_MES, "收到的消息-msg:" + msg.toString());
                    } catch (Exception e) {
                        e.printStackTrace();
                        sendBrodcast(NettyService.this, UPDATE_TXT_MES, "COAP PARSER报错!!e=" + e.getLocalizedMessage());
                        LogUtil.v("LoginHandler", "COAP PARSER报错!!e=" + e.getLocalizedMessage());
                    }

                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--writePos=" + writePos+"-readPos="+readPos);

//                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--msg=" + new Gson().toJson(msg));


                    if (msg != null) {
                        //维护readPos
                        readPos += msgLen + HEADLEN;
                        readPos %= TEMP_LEN; //维护readPos

                        queue.offer(msg);  //插入队列 add会报错  offer不会报错  peek()取得最早插入队列的数值
                        sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Producer-run()--readPos=" + readPos+"---queue.size="+queue.size());
                    }
                }
            }
        }
    }

    public class Consumer implements Runnable {

        private BlockingQueue<EmptyMessage> queue;

        private boolean ifRunning = true;

        public Consumer(BlockingQueue<EmptyMessage> q) {
            this.queue = q;
        }

        @Override
        public void run() {
            try {
                EmptyMessage msg;
                //获取并处理消息
                while (ifRunning) {
                    msg = queue.take(); //如果queue为空 会阻塞在这里

                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "Consumer-run()--处理消息--msg=" + new Gson().toJson(msg));

                    operateMessage(msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public void stop(){
            ifRunning = false;
        }
    }

    //获取headBytes 当前要解析的数据的头长度
    private int getTempbytesHeadLen() {

        byte[] headBytes = new byte[HEADLEN];
        System.arraycopy(tempBytes, readPos, headBytes, 0, HEADLEN);
        return getLenByHexString(headBytes);
    }

    //生产者消费模型 end


    private void sendBrodcast(Context context, String action, String mes) {

        Intent intent = new Intent(action);
        LogUtil.v("loginhandler", "sendBrodcast" + mes);
        intent.putExtra("mes", Utils.getDataTimeString() + "  " + mes);
        context.sendBroadcast(intent);
    }

    public final static String UPDATE_TXT_MES = "COM.ACTION.UPDATE_TXT_MES";

    static final int VALIDATE_LEN = 40;
    static final int DEVICEID_LEN = 12;
    static final int RSA_PUBLICKEY_LEN = 162;
    //sessionID和签名信息
    static final int SIGNATURE_LEN = 384;

    public static final int SESSION_LEN = 40;
    public static final int AES_KEY_LEN = 16;
    public static final int AES_IV_LEN = 16;


    static final int HELLO_MES_LEN = 50;
    static final int PING_MES_LEN = 18;

    int countMes = 0;


//    boolean ifHaveConnect = true;

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public synchronized void onMessageResponse(byte[] byteBuf) {

        sendBrodcast(this, UPDATE_TXT_MES, "收到的消息长度:" + byteBuf.length /*+ "---内容:" + new Gson().toJson(byteBuf)*/);

//        if(byteBuf.length % 16 != 2 && (byteBuf.length != VALIDATE_LEN && byteBuf.length !=SIGNATURE_LEN && byteBuf.length !=HELLO_MES_LEN)){
//            sendBrodcast(this, UPDATE_TXT_MES, "消息已忽略:" + byteBuf.length /*+ "---内容:" + new Gson().toJson(byteBuf)*/);
//            return;
//        }

        countMes++;
        LogUtil.v("LoginHandler", "收到信息数量统计=" + countMes);

        switch (byteBuf.length) {

            case VALIDATE_LEN: {
                validate(byteBuf);
                break;
            }
            case SIGNATURE_LEN: {
                secondHand(byteBuf);
                break;
            }
            case HELLO_MES_LEN: { //50位
                anylisedHelloMes(byteBuf);
                break;
            }
            default: {
                anylisedOtherMes(byteBuf);
            }
        }
    }

    int counter = 1;
    final int HEADLEN = 2; //头长度 0010

    //解析其他的消息
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private synchronized void anylisedOtherMes(byte[] byteBuf) {

        if (ifUseProducerAndConsumer) {

            int contentLen = byteBuf.length;

            //[0,10)
            //写入缓存tempBytes 判断writePos 如果(writePos+contentLen)小于TEMP_LEN 则直接拼接到tempBytes尾部
            if (writePos + contentLen <= TEMP_LEN) {
                System.arraycopy(byteBuf, 0, tempBytes, writePos, contentLen);
            } else { //判断writePos 如果(writePos+contentLen)大于TEMP_LEN 将超出的数据放到数组头部去
                int tailLen = TEMP_LEN - writePos;
                int headLen = contentLen - tailLen;
                sendBrodcast(NettyService.this, UPDATE_TXT_MES, "anylisedOtherMes--tailLen=" + tailLen+"  headLen="+headLen);
                System.arraycopy(byteBuf, 0, tempBytes, writePos, tailLen); //将尾部填满
                System.arraycopy(byteBuf, tailLen, tempBytes, 0, headLen); //将超出的数据放到数组头部去
            }

            //维护writePos
            writePos += contentLen;
            writePos %= TEMP_LEN;

            sendBrodcast(NettyService.this, UPDATE_TXT_MES, "anylisedOtherMes--writePos=" + writePos);
            return;
        }

        LogUtil.v("LoginHandler", "收到的消息数据-=" + RSAUtils.bytesToHexString(byteBuf));

        int lenghtAll = byteBuf.length; //总数据长度
        int hasAnalyseLen = 0; //已经解析的数据长度
        LogUtil.v("LoginHandler", "总数据长度=" + lenghtAll);

        while (hasAnalyseLen < lenghtAll) {

            LogUtil.v("LoginHandler", "循环处理消息hasAnalyseLen=" + hasAnalyseLen);

            byte lenBytes[] = new byte[HEADLEN];
            System.arraycopy(byteBuf, hasAnalyseLen, lenBytes, 0, HEADLEN);
            int singleLength = getLenByHexString(lenBytes);  //单个消息长度
            LogUtil.v("LoginHandler", "单个数据长度=" + singleLength);

            singleLength = Math.min(singleLength, lenghtAll - HEADLEN);

            byte singleBytes[] = new byte[singleLength]; //单个消息

            System.arraycopy(byteBuf, hasAnalyseLen + HEADLEN, singleBytes, 0, singleLength); //复制到单个数据

            LogUtil.v("LoginHandler", "解密前的数据singleBytes=" + RSAUtils.bytesToHexString(singleBytes));

            byte[] singleDecryptBytes = Encryptor.decrypt(Const.AES_KEY, Const.AES_IV_JIEMI, singleBytes);

            LogUtil.v("LoginHandler", "解密长度=" + singleLength + "解密结果==" + RSAUtils.bytesToHexString(singleDecryptBytes));
            sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解密结果==" + RSAUtils.bytesToHexString(singleDecryptBytes));

//            //更新解密iv
            System.arraycopy(singleBytes, 0, Const.AES_IV_JIEMI, 0, AES_IV_LEN);

            if (singleDecryptBytes == null) {
                LogUtil.v("LoginHandler", "解密失败!");
                sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解密失败:hasAnalyseLen=" + hasAnalyseLen);
            }

            EmptyMessage msg = null;
            try {
                msg = dataParser.parseMessage(singleDecryptBytes);
                sendBrodcast(NettyService.this, UPDATE_TXT_MES, "收到的消息-msg:" + msg.toString());
            } catch (Exception e) {
                e.printStackTrace();
                sendBrodcast(NettyService.this, UPDATE_TXT_MES, "COAP PARSER报错!!e=" + e.getLocalizedMessage());
                LogUtil.v("LoginHandler", "COAP PARSER报错!!e=" + e.getLocalizedMessage());
                hasAnalyseLen = hasAnalyseLen + singleLength + HEADLEN; //更新index值
                continue; //异常的话调到下一层循环
            }
            operateMessage(msg); //逐个处理数据
            hasAnalyseLen = hasAnalyseLen + singleLength + HEADLEN; //更新index值
        }
    }

    //处理消息
    private synchronized void operateMessage(EmptyMessage msg) {

        String url = null;
        try {
            url = msg.getOptions().getUriPath().get(0);
        } catch (Exception e) {
//            e.printStackTrace();
//            LogUtil.v("LoginHandler", "pingmsg.e=" + e.getLocalizedMessage());
        }

        if (url != null) { //非ping消息
            LogUtil.v("LoginHandler", "pingmsg.toString()11=" + new Gson().toJson(msg));
        }

        //根据URI类型判断
        if (url == null) { //ping类型
            if (msg.getType() == CoAP.Type.CON) {
                //todo 需要回一个ping ack消息 需要回一个ping
            } else if (msg.getType() == CoAP.Type.ACK) {
                //不用处理
            }
        } else if (url.equals("f")) { //FunctionCall类型
            //todo 需要返回一个"FunctionReturn": { code: Message.Code.CHANGED, type: Message.Type.NON },
//          或者 FunctionReturnError": { code: Message.Code.BAD_REQUEST, type: Message.Type.NON },

            String sss = new Gson().toJson(msg);
            LogUtil.v("loginHandler", "收到的functioncall消息=" + sss);

//            FunctionBean fbean = new Gson().fromJson(new Gson().toJson(msg),FunctionBean.class);
            FunctionBeanList fbean = new Gson().fromJson(new Gson().toJson(msg), FunctionBeanList.class);

            //f消息
//            f:playlist
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4247,"options":{"if_none_match":false,"uri_path_list":["f","playlist"],"uri_query_list":["[{\"url\":\"https://console.nexnovo.mobi/api/video/screens/a3851e7f0d1db60c0b5dda027f720e3a546006b3.mp4\",\"hash\":\"d+Djq3BvCSOSuCgtdGIrqg\u003d\u003d\"},{\"url\":\"https://console.nexnovo.mobi/api/video/screens/9ec861fea274f48c55fedf5e29f2c43cd29a8a92.mp4\",\"hash\":\"jn5ygVnkeUD43oji3vlLJA\u003d\u003d\"}]"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[4],"type":"CON"}
//
//            f:bash
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4256,"options":{"if_none_match":false,"uri_path_list":["f","bash"],"uri_query_list":["ifconfig"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[13],"type":"CON"}
//
//            f:reboot
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4255,"options":{"if_none_match":false,"uri_path_list":["f","reboot"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[12],"type":"CON"}
//
//            f:playpause
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4253,"options":{"if_none_match":false,"uri_path_list":["f","playpause"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[10],"type":"CON"}

            String config = fbean.getOptions().getUri_path_list().get(1);

            if (config.equals("playlist")) {  //视频列表

                String payListStr = fbean.getOptions().getUri_query_list().get(0);

                ArrayList<String> list = new ArrayList<>(); //播放列表
                try {
                    JSONArray array = new JSONArray(payListStr);
                    int len = array.length();
                    for (int i = 0; i < len; i++) {

                        JSONObject obj = array.getJSONObject(i);

                        String urlStr = obj.getString("url");
                        String hash = obj.getString("hash"); //用于判断下载下来的文件是否完整 MD5去比对 如果下载不完整需要重新下载

                        list.add(urlStr);
                    }

                } catch (JSONException e) {
                    LogUtil.v("loginHandler", "JSONException--e=" + e.getLocalizedMessage());
                    e.printStackTrace();
                }

                //payload为空
//            list.addAll(fbean.getOptions().getUri_query_list());  //当describer传fils0时 用这个获取
                LogUtil.v("loginHandler", "收到的functioncall消息-视频信息=" + new Gson().toJson(list));
                VideoUtils.getInstance(this).updateWebVideoList(list);
//                sendFunctionReturn(msg.getToken());

                sendFunctionReturn(msg.getToken(), "playlist");
            } else if (config.equals("playpause")) {  //暂停与开始

                boolean ifPlaying = VideoUtils.getInstance(this).toggle();
                String payload = ifPlaying ? "start" : "stop";
                sendFunctionReturn(msg.getToken(), payload);
            }
            //wifi和config
            else if (config.equals("bash")) {  //wifi(uri-query="iwlist wlan0 scan | egrep .....") 和 config按钮 (uri-query="ifconfig")
                sendFunctionReturn(msg.getToken(), "bash");
            } else if (config.equals("reboot")) {
                sendFunctionReturn(msg.getToken(), "Reboot");
            } else if (config.equals("dimming")) { //屏幕亮度

//              String lightValue = fbean.getOptions().ge
            }
        } else if (url.equals("v")) { //VariableRequest

            //            v消息
//            v:temperature
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4252,"options":{"if_none_match":false,"uri_path_list":["v","temperature"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[9],"type":"CON"}
//
//            v:brighness
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4248,"options":{"if_none_match":false,"uri_path_list":["v","brightness"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[5],"type":"CON"}
//
//            v:play_state
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4249,"options":{"if_none_match":false,"uri_path_list":["v","play_state"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[6],"type":"CON"}
//
//            v:light_sensor
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4250,"options":{"if_none_match":false,"uri_path_list":["v","light_sensor"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[7],"type":"CON"}
//
//            v:playstate
//            {"code":"POST","multicast":false,"acknowledged":false,"canceled":false,"destinationPort":0,"duplicate":false,"mid":4251,"options":{"if_none_match":false,"uri_path_list":["v","playstate"]},"rejected":false,"sourcePort":0,"timedOut":false,"timestamp":0,"token":[8],"type":"CON"}

            String config = msg.getOptions().getUriPath().get(1);

            LogUtil.v("loginhandler", "loginhandler-v消息--config=" + config);

            String payload = "";
            if (config.equals("play_state")) {  //返回当前的播放状态 'start':'stop';
                if (VideoUtils.getInstance(this).ifPlaying()) {
                    payload = "start";
                } else {
                    payload = "stop";
                }
            } else if (config.equals("playstate")) {

                if (Utils.ifScreenOn(this)) {
                    payload = "true";
                } else {
                    payload = "false";
                }
            } else if (config.equals("brightness")) {

                float brightness = Utils.getActivityBrightness(MyApllication.activity);
                payload = String.valueOf(brightness);
            } else if (config.equals("temperature")) {

                float temperature = MainActivity.temperature;
                payload = temperature + "°C";
            }

            //todo 需要返回一个"VariableRequest": { code: Message.Code.CHANGED, type: Message.Type.NON },
            sendVaribleReturn(++counter, msg.getToken(), payload);

        } else if (url.equals("d")) {
            sendDescribeReturn(++counter, msg.getToken());
        }
    }

    private void sendVaribleReturn(int i, byte[] token, final String payload) {

        VariableReturn fr = new VariableReturn();
        fr.setMID(i);
        fr.setToken(token);
//        fr.setPayload("OK");
        fr.setPayload(payload);

        //hello.setPayload("hello");
        //hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
        //hello.setToken("hhhhh".getBytes());
        DataSerializer DataSerializer = new DataSerializer();
        byte[] bb = DataSerializer.serializeRequest(fr);

        LogUtil.v("loginHandler", "组装的VaribleReturn消息=" + RSAUtils.bytesToHexString(bb));

//        byte[] bb=RSAUtils.hexStringToByte(spac);
//        byte[] bb = reqeustBytes;

        byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
        String spachex = RSAUtils.bytesToHexString(sendBytes);

        //更新iv的值
        //发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
        System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
//      System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);

//      logger.info("spac hex String : "+spachex);
//      logger.info("spac hex String lenth : "+sendBytes.length);

        StringBuilder sb = new StringBuilder();
        sb.append(getBeforeString(sendBytes.length)).append(spachex);

        LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());

        //String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
        byte[] bbb = RSAUtils.hexStringToByte(sb.toString());

        NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() {    //3
            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {                //4
                    Timber.d("Write auth successful");
                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送sendVaribleReturn成功-payload=" + payload);
                } else {
                    Timber.d("Write auth error");
                    WriteLogUtil.writeLogByThread("tcp auth error");
                }
            }
        });
    }

    void sendDescribeReturn(int count, byte[] token) {

        DescribeReturn fr = new DescribeReturn();
        fr.setMID(count);
        fr.setToken(token);

        DescribeBean bean = new DescribeBean(); //d消息是有的

        //v
        DescribeBean.VBean vbean = new DescribeBean.VBean();
        vbean.setTemperature("int32");
        vbean.setPlay_state("int32");
        vbean.setLight_sensor("int32");
        vbean.setPlaystate("int32");
        vbean.setBrightness("int32");

        bean.setV(vbean);

        //playpause
        DescribeBean.PlaypauseBean playPauseBean = new DescribeBean.PlaypauseBean();
        playPauseBean.setReturns("string");
        List<String> list = new ArrayList<String>();
        playPauseBean.setArgs(list);
        bean.setPlaypause(playPauseBean);

        //playlist
        DescribeBean.PlaylistBean playListBean = new DescribeBean.PlaylistBean();
        playListBean.setReturns("string");
        List<DescribeBean.PlaylistBean.ArgsBean> list1 = new ArrayList<DescribeBean.PlaylistBean.ArgsBean>();
        DescribeBean.PlaylistBean.ArgsBean argsBean = new DescribeBean.PlaylistBean.ArgsBean();
//      argsBean.setFile0("string"); //只会收到一个视频文件
        argsBean.setFiles("string"); //收到多个文件
        list1.add(argsBean);
        playListBean.setArgs(list1);

        bean.setPlaylist(playListBean);

        //xlist
        DescribeBean.XlistBean xListBean = new DescribeBean.XlistBean();

        xListBean.setReturns("string");
        List<DescribeBean.XlistBean.ArgsBeanX> list2 = new ArrayList<DescribeBean.XlistBean.ArgsBeanX>();
        DescribeBean.XlistBean.ArgsBeanX xargsBean = new DescribeBean.XlistBean.ArgsBeanX();
        xargsBean.setUrl("string");
        list2.add(xargsBean);
        xListBean.setArgs(list2);

        bean.setXlist(xListBean);

        //xbrightness
        DescribeBean.XbrightnessBean xBrightnessBean = new DescribeBean.XbrightnessBean();
        xBrightnessBean.setReturns("string");
        List<DescribeBean.XbrightnessBean.ArgsBeanXX> list3 = new ArrayList<DescribeBean.XbrightnessBean.ArgsBeanXX>();
        DescribeBean.XbrightnessBean.ArgsBeanXX xXargsBean = new DescribeBean.XbrightnessBean.ArgsBeanXX();
        xXargsBean.setLevel("uint16");
        list3.add(xXargsBean);
        xBrightnessBean.setArgs(list3);

        bean.setXbrightness(xBrightnessBean);

        //xstate
        DescribeBean.XstateBean xStateBean = new DescribeBean.XstateBean();

        xStateBean.setReturns("string");
        List<DescribeBean.XstateBean.ArgsBeanXXX> list4 = new ArrayList<DescribeBean.XstateBean.ArgsBeanXXX>();
        DescribeBean.XstateBean.ArgsBeanXXX xxxArgsBean = new DescribeBean.XstateBean.ArgsBeanXXX();
        xxxArgsBean.setState("string");
        list4.add(xxxArgsBean);
        xStateBean.setArgs(list4);

        bean.setXstate(xStateBean);

        //reboot
        DescribeBean.RebootBean rebootBean = new DescribeBean.RebootBean();

        List<String> list10 = new ArrayList<String>();
        rebootBean.setArgs(list10);
        rebootBean.setReturns("string");
        bean.setReboot(rebootBean);

        //bash
        DescribeBean.BashBean bashBean = new DescribeBean.BashBean();

        bashBean.setReturns("string");
        List<DescribeBean.BashBean.ArgsBeanXXXX> list6 = new ArrayList<DescribeBean.BashBean.ArgsBeanXXXX>();
        DescribeBean.BashBean.ArgsBeanXXXX xxxxArgsBean = new DescribeBean.BashBean.ArgsBeanXXXX();
        xxxxArgsBean.setCommand("string");
        list6.add(xxxxArgsBean);
        bashBean.setArgs(list6);
        bean.setBash(bashBean);


        String payload = new Gson().toJson(bean);

//        LogUtil.v("loginHandler", "DescribeReturnPayload=" + payload);

//        String test = "{\"v\":{\"temperature\":\"int32\",\"play_state\":\"int32\",\"light_sensor\":\"int32\",\"playstate\":\"int32\",\"brightness\":\"int32\"},\"playpause\":{\"returns\":\"string\",\"args\":[]},\"playlist\":{\"returns\":\"string\",\"args\":[{\"file0\":\"string\"}]},\"xlist\":{\"returns\":\"string\",\"args\":[{\"url\":\"string\"}]},\"xbrightness\":{\"returns\":\"string\",\"args\":[{\"level\":\"uint16\"}]},\"xstate\":{\"returns\":\"string\",\"args\":[{\"state\":\"string\"}]},\"reboot\":{\"returns\":\"string\",\"args\":[]},\"bash\":{\"returns\":\"string\",\"args\":[{\"command\":\"string\"}]}}";

        String test = "{\"v\":{\"temperature\":\"int32\",\"play_state\":\"int32\",\"light_sensor\":\"int32\",\"playstate\":\"int32\",\"brightness\":\"int32\"}," +
                "\"playpause\":{\"returns\":\"string\",\"args\":[]},\"playlist\":{\"returns\":\"string\",\"args\":[{\"file0\":\"string\"}]},\"xlist\":{\"returns\":\"string\",\"args\":[{\"url\":\"string\"}]},\"xbrightness\":{\"returns\":\"string\",\"args\":[{\"level\":\"uint16\"}]},\"xstate\":{\"returns\":\"string\",\"args\":[{\"state\":\"string\"}]},\"reboot\":{\"returns\":\"string\",\"args\":[]},\"bash\":{\"returns\":\"string\",\"args\":[{\"command\":\"string\"}]}}";

        LogUtil.v("loginHandler", "DescribeReturn--test=" + test);

        LogUtil.v("loginHandler", "DescribeReturn--payload=" + payload);

//        fr.setPayload(test);
        fr.setPayload(payload);

        //hello.setPayload("hello");
        //hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
        //hello.setToken("hhhhh".getBytes());
        DataSerializer DataSerializer = new DataSerializer();
        byte[] bb = DataSerializer.serializeRequest(fr);

        LogUtil.v("loginHandler", "DescribeReturn=" + RSAUtils.bytesToHexString(bb));

        LogUtil.v("loginHandler", "Const.AES_KEY=" + RSAUtils.bytesToHexString(Const.AES_KEY) + "--IV=" + RSAUtils.bytesToHexString(Const.AES_IV_JIAMI));

//        byte[] bb=RSAUtils.hexStringToByte(spac);
//        byte[] bb = reqeustBytes;
        byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
        String spachex = RSAUtils.bytesToHexString(sendBytes);

        LogUtil.v("loginHandler", "Descri加密后长度=" + sendBytes.length);

        //更新哪个iv的值勒 RSAUTILS
        //发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
        System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
//        System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);

//        logger.info("spac hex String : "+spachex);
//        logger.info("spac hex String lenth : "+sendBytes.length);

        StringBuilder sb = new StringBuilder();
        sb.append(getBeforeString(sendBytes.length)).append(spachex);

        LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());

        //String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
        byte[] bbb = RSAUtils.hexStringToByte(sb.toString());

        NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() {    //3
            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {                //4
                    Timber.d("Write auth successful");
                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送sendDescribeReturn成功");
                } else {
                    Timber.d("Write auth error");
                    WriteLogUtil.writeLogByThread("tcp auth error");
                }
            }
        });
    }

    //通过长度拼接00X0
    static String getBeforeString(int len) {

        byte[] b = new byte[2];
        byte b0 = (byte) (len >>> 8);
        byte b1 = (byte) (len & 255);
        b[0] = b0;
        b[1] = b1;
        return RSAUtils.bytesToHexString(b);
    }

    /**
     * 十六进制字符串转int
     *
     * @param bs
     * @return
     */
    int getLenByHexString(byte[] bs) {

//        int len =  ((bs[0] << 8) + bs[1]);
//        LogUtil.v("loginhandler","len="+len);
//        return len;

        return Integer.valueOf(RSAUtils.bytesToHexString(bs), 16);
    }

//    public static void main(String[] args){
//
//        System.out.println(getBeforeString(1));
//        System.out.println(getBeforeString(2));
//        System.out.println(getBeforeString(16));
//        System.out.println(getBeforeString(48));
//
//    }


    void sendFunctionReturn(byte[] token, final String payload) {

        FunctionReturn fr = new FunctionReturn();
        fr.setMID(++counter);
        fr.setToken(token);
//        fr.setPayload("OK");
        fr.setPayload(payload);

        //hello.setPayload("hello");
        //hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
        //hello.setToken("hhhhh".getBytes());
        DataSerializer DataSerializer = new DataSerializer();
        byte[] bb = DataSerializer.serializeRequest(fr);

        LogUtil.v("loginHandler", "组装的FunctionReturn消息=" + RSAUtils.bytesToHexString(bb));

//        byte[] bb=RSAUtils.hexStringToByte(spac);
//        byte[] bb = reqeustBytes;

        byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
        String spachex = RSAUtils.bytesToHexString(sendBytes);

        //更新哪个iv的值
        //发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
        System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
//      System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);

//      logger.info("spac hex String : "+spachex);
//      logger.info("spac hex String lenth : "+sendBytes.length);

        StringBuilder sb = new StringBuilder();
        sb.append(getBeforeString(sendBytes.length)).append(spachex);

        LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());

        //String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
        byte[] bbb = RSAUtils.hexStringToByte(sb.toString());

        NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() {    //3
            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {                //4
                    Timber.d("Write auth successful");
                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送sendFunctionReturn成功--payload=" + payload);
                } else {
                    Timber.d("Write auth error");
                    WriteLogUtil.writeLogByThread("tcp auth error");
                }
            }
        });
    }

    DataParser dataParser = new DataParser();

    //解析hello消息
    private void anylisedHelloMes(byte[] byteBuf) {

        LogUtil.v("LoginHandler", "收到的hellobyte-=" + new Gson().toJson(byteBuf));

        byte[] bb1 = new byte[byteBuf.length - 2];
        System.arraycopy(byteBuf, 2, bb1, 0, byteBuf.length - 2);

//      sendBrodcast(NettyService.this, UPDATE_TXT_MES, "长度="+(byteBuf.length - 2)+"  收到的hello消息="+ RSAUtils.bytesToHexString(byteBuf));

        byte[] decryptBs = Encryptor.decrypt(Const.AES_KEY, Const.AES_IV_JIEMI, bb1);
//        LogUtil.v("LoginHandler", "解密hello数据-decryptBs=" + RSAUtils.bytesToHexString(decryptBs));

        //更新解密iv 不管iv放在前面还是后面  都无法正常解析hello消息
        System.arraycopy(byteBuf, 2, Const.AES_IV_JIEMI, 0, AES_IV_LEN);

//        sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解密的hello消息="+ RSAUtils.bytesToHexString(decryptBs));

        //接收hello消息
//        EmptyMessage hellomsg =dataParser.parseMessage(decryptBs);
//        System.out.println(hellomsg.toString());
//        LogUtil.v("LoginHandler","解析出来的hello消息="+ new Gson().toJson(hellomsg));
//        sendBrodcast(NettyService.this, UPDATE_TXT_MES, "解析出来的hello消息="+ new Gson().toJson(hellomsg));

        //解密后更换iv的值(3-18位) 用解密前的数据 这里更新的话 发过去的心跳消息就不能被解析
        //开启定时器
        openHeartSend();
    }

    //发送心跳消息
    private void openHeartSend() {

        // 自定义心跳,每隔自定义时间向服务器发送心跳包
        mScheduledExecutorService = Executors.newScheduledThreadPool(1);

//        mScheduledExecutorService.scheduleAtFixedRate()
        mScheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {

                LogUtil.v("LoginHandler", "发送心跳信息");

//                //封装心跳信息
//                String heartString = "41004f3e02";
//                StringBuffer sbff = new StringBuffer(heartString);

//                sbff.append("0010");
//                byte [] bs = RSAUtils.hexStringToByte(sbff.toString()) ;
//                byte[] sendBs = Encryptor.decrypt(Const.AES_KEY,Const.AES_IV_JIAMI,bs);
//
//                //更新IV
//                System.arraycopy(sendBs,2,Const.AES_IV_JIAMI,0,AES_IV_LEN);

                Ping ping = new Ping();
                ping.setMID(++counter);
                DataSerializer DataSerializer = new DataSerializer();
                byte[] bb = DataSerializer.serializeRequest(ping);
                LogUtil.v("LoginHandler", "发送心跳信息组装=" + RSAUtils.bytesToHexString(bb));
//              String spac = "41004f3e02";
//              byte[] bb=RSAUtils.hexStringToByte(spac);
                byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);

                LogUtil.v("LoginHandler", "发送心跳信息2222");
                String spachex = RSAUtils.bytesToHexString(sendBytes);

                //发送完hello 更新iv值 加完密的数据的前十六位byte 除了前缀0010
                System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);

                StringBuilder sb = new StringBuilder();
                sb.append(getBeforeString(sendBytes.length)).append(spachex);

                LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());

                byte[] sendBs = RSAUtils.hexStringToByte(sb.toString());

                NettyClient.getInstance().sendMsgToServer(sendBs, new ChannelFutureListener() {    //3
                    @Override
                    public void operationComplete(ChannelFuture future) {
                        if (future.isSuccess()) {                //4
                            Timber.d("Write heartbeat successful");
                            LogUtil.v("LoginHandler", "发送心跳成功");
                            sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送心跳成功");
                        } else {

                            LogUtil.v("LoginHandler", "发送心跳信息失败");
                            Timber.e("Write heartbeat error");
                            WriteLogUtil.writeLogByThread("heartbeat error");
                        }
                    }
                });
            }
        }, 25, 25, TimeUnit.SECONDS);
    }


    //第二次握手 获取签名信息
    void secondHand(byte[] byteBuf) {

        final int len1 = 128;
        final int len2 = 256;

        byte byte1[] = new byte[len1];

        System.arraycopy(byteBuf, 0, byte1, 0, len1);

        try {

            Const.DEVICE_PUBLIC_KEY = Utils.getConfigProperties(this).getProperty("devicePrivateKeyPck8");
            LogUtil.v("loginHandler", "Const.DEVICE_PRIVATE_KEY_PCK8=" + Const.DEVICE_PRIVATE_KEY_PCK8.length());
            RSAPrivateKey privateKey = RSAUtils.getPrivateKey(Const.DEVICE_PRIVATE_KEY_PCK8);

            //保存sessionId
//            Const.SESSION_ID = RSAUtils.privateDecrypt(byte1,privateKey);
            System.arraycopy(RSAUtils.privateDecrypt(byte1, privateKey), 0, Const.SESSION_ID, 0, SESSION_LEN);

            System.arraycopy(RSAUtils.privateDecrypt(byte1, privateKey), 0, Const.AES_KEY, 0, AES_KEY_LEN);
            System.arraycopy(RSAUtils.privateDecrypt(byte1, privateKey), AES_KEY_LEN, Const.AES_IV_JIAMI, 0, AES_IV_LEN);

//            System.arraycopy(RSAUtils.privateDecrypt(byte1,privateKey),AES_KEY_LEN,Const.AES_IV_JIEMI,0,AES_IV_LEN);

            LogUtil.v("loginHandler", "解密STRING=" + RSAUtils.bytesToHexString(Const.SESSION_ID));

        } catch (Exception e) {

            LogUtil.v("loginHandler", "解密STRING--E==" + e.getLocalizedMessage());
            e.printStackTrace();
        }

        Const.SIGNATURE_MES = new byte[len2];
        System.arraycopy(byteBuf, len1, Const.SIGNATURE_MES, 0, len2); //直接把签名信息保存到全局变量里

        try {
            coapConnect("hello");
        } catch (Exception e) {
            LogUtil.v("loginHandler", "coapConnect-E==" + e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    //发送hello消息
    void coapConnect(String mes) throws Exception {

        String uriStr = "coap+tcp://" + Const.HOST + ":" + Const.TCP_PORT;
//        if(coapClient == null){
//            LogUtil.v("loginHandler","coapConnect-uriStr=="+uriStr);
//            coapClient = new CoapClient();
//        }
//
        Request request = new Request(CoAP.Code.POST);
        Token token = new Token();
        request.setToken(token);
//
//        coapClient.setURI(String.valueOf(new URI(uriStr+"/h")));
        coapClient
//        CoapResponse response = coapClient.post("hello",0);
//        LogUtil.v("loginHandler","coapConnect-coapClient=response="+new Gson().toJson(response));

//        TcpDataSerializer tsz = new TcpDataSerializer();
//        byte[] reqeustBytes = tsz.getByteArray(request);
//        8602313233343536b168ff48656c6c6f //生成的requestString有三十二位

//        MessageDataSerialzer tsz = new MessageDataSerialzer();
//        byte[] reqeustBytes = tsz.getByteArray(request); //这个格式生成的位数有十六位  b168ff48656c6c6f  //等于没有生成头哦

//        byte[] reqeustBytes =  MessageDataSerialzer.serializeOptionsAndPayload(request);
//          LogUtil.v("loginHandler","requestToByteStringMes="+RSAUtils.bytesToHexString(reqeustBytes));

//          String spac ="510233a901b168"; //老外提供的原始数据

        Hello hello = new Hello();
        hello.setMID(counter);
        //hello.setPayload("hello");
        //hello.setPayload("{\"orderNumber\": \"08171620573119330131\"}");
        //hello.setToken("hhhhh".getBytes());
        DataSerializer DataSerializer = new DataSerializer();
        byte[] bb = DataSerializer.serializeRequest(hello);

        LogUtil.v("loginHandler", "组装的hello消息=" + RSAUtils.bytesToHexString(bb));

//        byte[] bb=RSAUtils.hexStringToByte(spac);
//        byte[] bb = reqeustBytes;

        byte[] sendBytes = Encryptor.encrypt(Const.AES_KEY, Const.AES_IV_JIAMI, bb);
        String spachex = RSAUtils.bytesToHexString(sendBytes);

        //更新哪个iv的值勒 RSAUTILS
        //发送完hello 更新iv值 加密数据的前十六位byte 除了前缀0010
        System.arraycopy(sendBytes, 0, Const.AES_IV_JIAMI, 0, AES_IV_LEN);
//        System.arraycopy(sendBytes,0,Const.AES_IV_JIEMI,0,AES_IV_LEN);

//        logger.info("spac hex String : "+spachex);
//        logger.info("spac hex String lenth : "+sendBytes.length);

        StringBuilder sb = new StringBuilder();
        sb.append(getBeforeString(sendBytes.length)).append(spachex);

        LogUtil.v("loginHandler", "发送的十六进制数据" + sb.toString());

        //String s = "0010c55f3330b20d282861f81a6dbe3d92cd";
        byte[] bbb = RSAUtils.hexStringToByte(sb.toString());

        NettyClient.getInstance().sendMsgToServer(bbb, new ChannelFutureListener() {    //3
            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {                //4
                    Timber.d("Write auth successful");
                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送hello成功");
                } else {
                    Timber.d("Write auth error");
                    WriteLogUtil.writeLogByThread("tcp auth error");
                }
            }
        });
    }

    //第一次握手 发送验证消息 及本地的密钥和设备信息
    void validate(byte[] byteBuf) {

        byte[] rsaDeviceBytes = null;
        try {
//                KeyPair pair = RSAUtil.getKeyPair();
//                String  privateKey = RSAUtil.getPrivateKey(pair);
//                String  publicKey = RSAUtil.getPublicKey(pair);
//                //本地保存公钥和密钥
//                rsaDeviceBytes = RSAUtil.getPublicKeyBeforeBase64(pair);
//                BASE64Decoder decoder = new BASE64Decoder();


            Const.DEVICE_PUBLIC_KEY = Utils.getConfigProperties(this).getProperty("devicePublicKey");

            LogUtil.v("LoginHandler", "Const.DEVICE_PUBLIC_KEY.length=" + Const.DEVICE_PUBLIC_KEY.length());

            byte bytes[] = RSAUtils.base642Byte(Const.DEVICE_PUBLIC_KEY);
            LogUtil.v("LoginHandler", "bytes.length=" + bytes.length);

            rsaDeviceBytes = bytes;

        } catch (Exception e) {
            LogUtil.v("LoginHandler", "Exception=e:" + e.getLocalizedMessage());
            e.printStackTrace();
        }

        //发送认证的字符串
        byte bytes[] = new byte[VALIDATE_LEN + DEVICEID_LEN + RSA_PUBLICKEY_LEN];
        System.arraycopy(byteBuf, 0, bytes, 0, VALIDATE_LEN); //123456789012//模拟deviceId
        System.arraycopy("939030010983".getBytes(), 0, bytes, VALIDATE_LEN, DEVICEID_LEN); //123456789012//模拟deviceId
        System.arraycopy(rsaDeviceBytes, 0, bytes, VALIDATE_LEN + DEVICEID_LEN, RSA_PUBLICKEY_LEN);

        //加密
        byte[] sendBytes = null;
        RSAPublicKey publicKey = null;

//      sendBrodcast(this,UPDATE_TXT_MES, "加密前的串:"+Utils.bytesToHexString(bytes));

        //从配置文件里读取服务端公钥
        Const.SERVER_PUBLIC_KEY_DEBUG = Utils.getConfigProperties(this).getProperty("serverPublicKeyDebug");

//        LogUtil.v("LoginHandler", "读取的配置文件内容:" + Const.SERVER_PUBLIC_KEY_DEBUG);

        try {
//          publicKey = RSAUtils.getPublicKey(Const.SERVER_PUBLIC_KEY); //5680
            publicKey = RSAUtils.getPublicKey(Const.SERVER_PUBLIC_KEY_DEBUG); //5666
            //如何没有收到心跳消息咋整
            sendBytes = RSAUtils.publicEncrypt(bytes, publicKey);
            LogUtil.v("LoginHandler", "加密后的串:" + Utils.bytesToHexString(sendBytes));
//            sendBrodcast(this,UPDATE_TXT_MES, "加密后的串:"+Utils.bytesToHexString(sendBytes));
        } catch (Exception e) {
            LogUtil.v("LoginHandler", "e" + e.getLocalizedMessage());
            e.printStackTrace();
            sendBrodcast(this, UPDATE_TXT_MES, "加密异常:" + e.getLocalizedMessage());
            return;
        }

        NettyClient.getInstance().sendMsgToServer(sendBytes, new ChannelFutureListener() {    //3
            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {                //4
                    Timber.d("Write auth successful");
                    sendBrodcast(NettyService.this, UPDATE_TXT_MES, "发送认证信息成功");
                } else {
                    Timber.d("Write auth error");
                    WriteLogUtil.writeLogByThread("tcp auth error");
                }
            }
        });
    }

    Producer producer;
    Consumer consumer;
    private void connect() {
        if (!NettyClient.getInstance().getConnectStatus()) {
            NettyClient.getInstance().connect();//连接服务器
        }

        if(ifUseProducerAndConsumer) {
            //创建大小为50的 BlockingQueue
            BlockingQueue<EmptyMessage> queue = new ArrayBlockingQueue<>(50);
            producer = new Producer(queue);
            consumer = new Consumer(queue);
            //开启 producer线程向队列中生产消息
            new Thread(producer).start();
            //开启 consumer线程 中队列中消费消息
            new Thread(consumer).start();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
        shutdown();
        NettyClient.getInstance().setReconnectNum(0);
        NettyClient.getInstance().disconnect();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public class NetworkReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) { // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI
                        || activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    connect();
                }
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值