SunVoteAdapterManagerFactroy.java 7.24 KB
package com.sunvote.sunvoteadapter;

import com.sunvote.cmd.BaseCmd;
import com.sunvote.cmd.ICmd;
import com.sunvote.protocal.Protocol;
import com.sunvote.udptransfer.UDPModule;
import com.sunvote.udptransfer.work.WorkThread;
import com.sunvote.util.ByteUtil;
import com.sunvote.util.LogUtil;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Elvis on 2017/11/29 17:07
 * Email:Eluis@psunsky.com
 * 版权所有:长沙中天电子设计开发有限公司
 * Description: SunVoteAdapterManagerFactroy
 */
public class SunVoteAdapterManagerFactroy {
    private static volatile SunVoteAdapterManagerFactroy ourInstance = null;
    private static String TAG = "SunVote";

    private UDPModule client = null;

    private InputStream mInputStream;
    private OutputStream mOutputStream;
    private WorkThread receiverWorkThread;
    private boolean isRunning = false;

    private List<IBottomCommandReceiver> mCommandReceivingList = new ArrayList<>();

    public boolean isRunning() {
        return isRunning;
    }

    public static SunVoteAdapterManagerFactroy getInstance() {
        if(ourInstance == null){
            synchronized (SunVoteAdapterManagerFactroy.class){
                if(ourInstance == null){
                    ourInstance = new SunVoteAdapterManagerFactroy();
                }
            }
        }
        return ourInstance;
    }

    public void registerCommandReceiverListener(IBottomCommandReceiver receiver){
        mCommandReceivingList.add(receiver);
    }

    public void unRegisterCommandReceiverListener(IBottomCommandReceiver receiver){
        mCommandReceivingList.remove(receiver);
    }

    public void clearReceiverListener(){
        mCommandReceivingList.clear();
    }

    private SunVoteAdapterManagerFactroy() {
    }

    public void start(){
        if(!isRunning()) {
            isRunning = true;
            client = new UDPModule();
            mOutputStream = client.getOutputStream();
            mInputStream = client.getInputStream();
            if (receiverWorkThread != null) {
                receiverWorkThread.destroyObject();
            }
            receiverWorkThread = new WorkThread("SunVoteAdapterManagerFactroy");
            reciveMsgBean.executeMethod = executeMethod;
            receiverWorkThread.sendMessage(reciveMsgBean);
        }
    }

    public void stop(){
        if(isRunning()){
            isRunning = false;
            if (receiverWorkThread != null) {
                receiverWorkThread.destroyObject();
            }
            if(mInputStream != null) {
                try {
                    mInputStream.close();
                } catch (IOException e) {
                    LogUtil.e(TAG,e);
                }
                mInputStream = null;
            }
            if(mOutputStream != null){
                try {
                    mOutputStream.close();
                } catch (IOException e) {
                    LogUtil.e(TAG,e);
                }
            }
            mOutputStream = null;
            client = null;
        }
    }

    private WorkThread.MessageBean reciveMsgBean = new WorkThread.MessageBean();

    private WorkThread.ExecuteMethod executeMethod = new WorkThread.ExecuteMethod() {
        @Override
        public void execute(WorkThread.MessageBean messageBean) {
            if(mInputStream != null){
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] bytes = new byte[1024];
                int tmpLength = -1 ;
                while(isRunning()){
                    try {
                        tmpLength = mInputStream.read(bytes);
                        if(tmpLength < 0){
                            break;
                        }
                        // 1. 先检测读取数据到缓冲区
                        byteArrayOutputStream.write(bytes,0,tmpLength);
                        // 2. 判断缓冲区的数据标志是否存在
                        if(byteArrayOutputStream.size() >= 3){
                             byte[] temp = byteArrayOutputStream.toByteArray();
                             int find = ByteUtil.findBytes(temp,Protocol.HEADER,0);
                             if(find >= 0){
                                 // 3. 标志存在,则继续读取长度
                                 if(byteArrayOutputStream.size() >= find + 4){
                                    int length = ByteUtil.byte1ToInt(byteArrayOutputStream.toByteArray()[find+3]);
                                    if(byteArrayOutputStream.size() >= find + 4 + length){
                                        ByteArrayOutputStream tmp = new ByteArrayOutputStream();
                                        // 4. 根据长度读取包的内容
                                        for(int i = find ; i < find + 4 + length;i++){
                                            // 5. 截取包的内容,向外抛出,处理,接着读取下一个包
                                            tmp.write(temp[i]);
                                        }
                                        // 6. 抛出处理
                                        LogUtil.i(TAG,"命令包数据",tmp.toByteArray());
                                        ICmd cmd = BaseCmd.parse(tmp.toByteArray(),tmp.size());
                                        sendCmdToCall(cmd);
                                        // 7. 剩余数据重新打包处理
//                                        byteArrayOutputStream = new ByteArrayOutputStream();
                                        byteArrayOutputStream.reset();
                                        for(int i = find + 4 + length ; i < temp.length ; i++) {
                                            byteArrayOutputStream.write(temp[i]);
                                        }
                                    }
                                 }
                             }
                        }
                        if(byteArrayOutputStream.size() > 2048){
                            LogUtil.i(TAG,"被恶意攻击?或者传输数据错误?丢弃处理!",byteArrayOutputStream.toByteArray());
                            byteArrayOutputStream.reset();
                        }
                    } catch (Exception e) {
                        LogUtil.e(TAG,e);
                    }
                }
            }
        }
    };

    public boolean sendCmd(ICmd cmd){
        if(isRunning()) {
            Protocol<ICmd> protocol = new Protocol<>();
            protocol.setEnableMatchCode(false);
            protocol.setCmd(cmd);
            if (mOutputStream != null) {
                try {
                    mOutputStream.write(protocol.toBytes());
                    mOutputStream.flush();
                    return true;
                } catch (Exception e) {
                    LogUtil.e(TAG, e);
                }
            }
        }
        return false;
    }

    private void sendCmdToCall(ICmd cmd){
        if(mCommandReceivingList != null && mCommandReceivingList.size() > 0) {
            for (IBottomCommandReceiver receiver : mCommandReceivingList) {
                receiver.onReceiverCmd(cmd);
            }
        }
    }

}