基于netty基础上的网关解析和消息处理(三)

netty业务处理有两个文件 一个是xxxServer(服务创建) 一个是xxxServerHandler(消息处理响应)

在基于netty基础上的网关解析和消息处理(二)中,在业务中我们增加是

synchronized和SendMap记录发送消息后的唯一标识

在本章中需要释放锁,如果在异常的地方也需要释放掉锁,要不然线程会出现阻塞情况。

synchronized (TaskDistribution.class) {
    log.info("TaskDistribution.class.notify()  释放");
    TaskDistribution.class.notify();
    TaskDistribution.SendMap.values().removeIf(value -> value.contains(checkKey));
}

 

本文章以其中一个厂家为例:

下面是消息处理响应(BlueChipsServerHandler )

package com.openapi.protocol;

import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import org.apache.log4j.Logger;

import java.io.UnsupportedEncodingException;
import java.util.Date;

public class BlueChipsServerHandler extends ChannelInboundHandlerAdapter {
    private final Logger log = Logger.getLogger(BlueChipsServerHandler.class);

    //异步发送
    public int sendMsg(String dut, String data ) throws Exception {
        ChannelHandlerContext ctx = BlueChipsServer.map.get(dut);
        if( null == ctx ){
            log.error(" 无法找到该设备 设备编号: " +  dut);
            return BlueChips.RET_DEVICE_OFFLINE;
        }
        String strlen = String.format("%04d", data.getBytes("UTF-8").length);
        String packageData = "\n"+ strlen + data+ "\r";
        ChannelFuture future  = ctx.writeAndFlush(Unpooled.copiedBuffer(packageData, CharsetUtil.UTF_8));
        future.await();
        if(future.isSuccess()) {
            return BlueChips.RET_SUCESS;
        } else {
            return BlueChips.RET_DELIVERY_FAILED;
        }
    }

    /*
     * channelAction
     * channel 通道 action 活跃的
     * 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
     */
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info(ctx.channel().remoteAddress().toString() + " 通道已激活!");
    }

    /*
     * channelInactive
     * channel 通道 Inactive 不活跃的
     * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     */
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info(ctx.channel().remoteAddress().toString() + " 通道不活跃!");
        // 关闭流
    }

    /**
     * @author Taowd
     * TODO  此处用来处理收到的数据中含有中文的时  出现乱码的问题
     * 2017年8月31日 下午7:57:28
     * @param buf
     * @return
     */
    private String getMessage(ByteBuf buf) {
        byte[] con = new byte[buf.readableBytes()];
        buf.readBytes(con);
        try {
            return new String(con, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 功能:读取服务器发送过来的信息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 第一种:接收字符串时的处理
        ByteBuf buf = (ByteBuf) msg;
        String data = getMessage(buf);

        int len = Integer.parseInt(data.substring(1,5));
        String jsondata = data.substring(5,len+5);
        System.out.println("蓝筹收到设备请求数据 jsondata:" + jsondata + " len:" + len +  " data:"+data);

        JSONObject object = JSONObject.parseObject(jsondata);
        String dut = object.get("dut").toString();
        if (BlueChipsServer.map.get(dut) == null || !BlueChipsServer.map.get(dut).equals(ctx)) {
            BlueChipsServer.map.put(dut, ctx);
            log.info("新增加map:" + dut + " Time: " + new Date() + " type: " + object.get("type"));
        }

        BlueChips blueChips = new BlueChips();
        JSONObject retdata = new JSONObject();

        if (BlueChips.JST_BEAT == Integer.parseInt( object.get("type").toString() )) {
            retdata = blueChips.Heartbeat(object);
        }else if (BlueChips.JST_EVENT == Integer.parseInt( object.get("type").toString() )) {
            retdata = blueChips.IncidentReport(object);
        }else if(BlueChips.JST_SAVE_USER == Integer.parseInt( object.get("type").toString())||
                BlueChips.JST_DEL_USER == Integer.parseInt( object.get("type").toString())||
                BlueChips.JST_ANDROID_SAVE_FACE == Integer.parseInt( object.get("type").toString())||
                BlueChips.JST_ANDROID_DEL_FACE == Integer.parseInt( object.get("type").toString())||
                BlueChips.JST_SAVE_CARD == Integer.parseInt( object.get("type").toString())||
                BlueChips.JST_DEL_CARD == Integer.parseInt( object.get("type").toString() ) ){

            String checkKey = TaskDistribution.SendMap.get(dut);
            String Arrays = object.get("suc").toString();
            if(Arrays.indexOf(checkKey) >0){
                synchronized (TaskDistribution.class) {
                    log.info("TaskDistribution.class.notify()  释放");
                    TaskDistribution.class.notify();
                    TaskDistribution.SendMap.values().removeIf(value -> value.contains(checkKey));
                }
            }else {
                log.error(" 没有找到匹配的释放资源 Arrays: " + Arrays + " checkKey;" + checkKey);
            }

        }else {
            log.info("蓝筹科技设备 无法找到相对应的包:" + data);
        }
        if(!retdata.isEmpty()) {
            String strlen = String.format("%04d", retdata.toString().getBytes("UTF-8").length);
            String packageData = "\n" + strlen + retdata.toString() + "\r";

            ctx.writeAndFlush(Unpooled.copiedBuffer(packageData, CharsetUtil.UTF_8)); // 必须有flush
        }
    }

    /**
     * 功能:读取完毕客户端发送过来的数据之后的操作
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("服务端接收数据完毕..");
        // 第一种方法:写一个空的buf,并刷新写出区域。完成后关闭sock channel连接。
//        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

    /**
     * 功能:服务端发生异常的操作
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        log.info("异常信息:\r\n" + cause.getMessage());
    }
}

 下面是服务创建(BlueChipsServer)

package com.openapi.protocol;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.string.StringEncoder;
import org.apache.log4j.Logger;

import java.nio.charset.Charset;
import java.util.*;

public class BlueChipsServer implements Runnable{
    private final Logger log = Logger.getLogger(BlueChipsServer.class);
    private final int port;
    public  static Map<String, ChannelHandlerContext> map = new HashMap<String, ChannelHandlerContext>();

    public BlueChipsServer(int port) {
        this.port = port;
    }

    public void run() {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            ServerBootstrap sb = new ServerBootstrap();
            sb.option(ChannelOption.SO_BACKLOG, 1024);
            sb.group(group, bossGroup) // 绑定线程池
                    .channel(NioServerSocketChannel.class) // 指定使用的channel
                    .localAddress(this.port)// 绑定监听端口
                    .childHandler(new ChannelInitializer<SocketChannel>() { // 绑定客户端连接时候触发操作

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            log.info("蓝筹科技:有一客户端链接到本服务端");
                            log.info("IP:" + ch.remoteAddress().getHostName());
                            ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
                            ch.pipeline().addLast(new BlueChipsServerHandler()); // 客户端触发操作
                            ch.pipeline().addLast(new ByteArrayEncoder());
                        }
                    });

            ///单个netty是可以侦听多个端口的,一个端口一条线程,如果需要侦听多个端口,如下所示:
//            List<Integer> ports = Arrays.asList(2004, 2002);
//            Collection<Channel> channels = new ArrayList<>(ports.size());
//            for (int port : ports) {
//                Channel serverChannel = sb.bind(port).sync().channel();
//                channels.add(serverChannel);
//                log.info(BlueChipsServer.class + " 启动正在监听: " + serverChannel.localAddress());
//            }
//            for (Channel ch : channels) {
//                ch.closeFuture().sync();
//            }

            ChannelFuture cf = sb.bind().sync(); // 服务器异步创建绑定
            log.info(BlueChipsServer.class + " 启动正在监听: " + cf.channel().localAddress());
            cf.channel().closeFuture().sync(); // 关闭服务器通道
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                group.shutdownGracefully().sync(); // 释放线程池资源
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                bossGroup.shutdownGracefully().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

 

网关协议解析

package com.openapi.protocol;

import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.utils.HttpClient;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.openapi.controller.WebController;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/*********************************************************
本文件主要按照武汉蓝筹硬件相关协议形成一个内部数据组装
参照:门禁控制器远程通信规范V2.8.docx
创建人:wp
创建时间:2020-8-11
 **********************************************************/
@Component
public class BlueChips {
    private final static Logger log = Logger.getLogger(BlueChips.class);
    @Value("${eems.serviceIp}")
    private String serviceIp;

    //type 包类型
    public static final int JST_NULL = 0;
    public static final int JST_BEAT = 1;//心跳
    public static final int JST_EVENT = 2;//事件上报
    public static final int JST_CMD = 129;//直接指令
    public static final int JST_SAVE_CARD = 130;//存储卡号
    public static final int JST_DEL_CARD = 131;//删除卡号
    public static final int JST_FIND_CARD = 132;//对比卡号
    public static final int JST_SAVE_USER = 133;//存储用户标识
    public static final int JST_DEL_USER = 134;//删除用户标识
    public static final int JST_FIND_USER = 135;//对比用户标识
    public static final int JST_STORAGE_STAT = 136;//获取统计信息
    public static final int JST_ANDROID_SAVE_CARD = 140;//安卓设备存储卡号
    public static final int JJST_ANDROID_DEL_CARD = 141;//安卓设备删除卡号
    public static final int JST_ANDROID_SAVE_FACE = 150;//安卓设备存储人脸
    public static final int JST_ANDROID_DEL_FACE = 151;//安卓设备删除人脸
    public static final int JST_ANDROID_DEL_ORG = 160;//安卓设备删除公司
    public static final int JST_ANDROID_APP_UPGRADE = 170;//安卓设备程序升级
    public static final int JST_ANDROID_GET_LOG = 180;//安卓设备提取日志
    public static final int JST_ANDROID_VIDEO = 190;//安卓设备视频通话
    //res 返回结果
    public static final int GPR_MAIN = 0;//主包
    public static final int GPR_SUCESS = 1;//处理成功
    public static final int GPR_FAILD = 2;//处理失败
//    public static final int GPR_PARAM_ERROR = 3;//传入的参数有误
//    public static final int GPR_RES_NULL = 4;//需要获取的资源为空
//    public static final int GPR_RES_UNENOUGH = 5;//资源不够
//    public static final int GPR_NUM_OVERFLOW = 6;//参数超限
//    public static final int GPR_ROUTING_ERROR = 7;//程序错误
//    public static final int GPR_HARDWARD_ERROR = 8;//硬件错误
//    public static final int GPR_AUTH_ERROR = 9;//权限错误
//    public static final int GPR_TIMEOUT = 10;//超时
//    public static final int GPR_BUSY = 11;//忙

    //返回平台状态 0:待处理数据 1:正在处理 2:下发成功 3:下发失败 4:设备离线
    public static final int RET_SUCESS = 2;//处理成功
    public static final int RET_DELIVERY_FAILED = 3;//下发失败
    public static final int RET_DEVICE_OFFLINE = 4;//设备离线

    /**
     * 生成16位不重复的随机数
     * @return
     */
    public static long getGUID() {
        return System.currentTimeMillis()/1000;
    }
    public static String ReverseOrder(String CardID) {
        String CardNO = "";
        if(CardID.length()%2 != 0){
            log.error(" ReverseOrder 次卡反转失败,卡号异常!" + CardID);
            return  CardID;
        }

        for (int i = CardID.length(); i>0; i=i-2){
            CardNO += CardID.substring(i-2,i);
        }
        return  CardNO;
    }

    /**
     * local时间转换成UTC时间
     * @param localTime
     * @return
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    public static Date localToUTC(String localTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date localDate= null;
        try {
            localDate = sdf.parse(localTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        long localTimeInMillis=localDate.getTime();
        /** long时间转换成Calendar */
        Calendar calendar= Calendar.getInstance();
        calendar.setTimeInMillis(localTimeInMillis);
        /** 取得时间偏移量 */
        int zoneOffset = calendar.get(java.util.Calendar.ZONE_OFFSET);
        /** 取得夏令时差 */
        int dstOffset = calendar.get(java.util.Calendar.DST_OFFSET);
        /** 从本地时间里扣除这些差量,即可以取得UTC时间*/
        calendar.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
        /** 取得的时间就是UTC标准时间 */
        Date utcDate=new Date(calendar.getTimeInMillis());
        return utcDate;
    }
//    上行通信(设备发送给服务器)
    /*******************************************************************************
    由设备定期发出,30秒一次,超过3分钟不发送时,服务器判定设备离线,并断开连接。
    服务器收到心跳后,返回带有rtc字段的时间值,供设备校准当前时间。
    主包	{"dut":22600938,"type":1,"sn":41143,"res":0}
    回包	{"dut":22600938,"type":1,"sn":41143,"res":1,"rtc":1540288993}
    创建人:wp
    创建时间:2020-8-11
    ********************************************************************************/
    public  JSONObject Heartbeat(JSONObject object) {
        //设备主动上报数据,将心跳数据同步更新到redis里面去
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式 2020 08 24 10 46 13
        WebController.onlineMap.put(object.get("dut").toString(),df.format(new Date()));

        //根据设备上报数据返回处理结果
        JSONObject objectRet = new JSONObject();
        objectRet.put("dut",object.get("dut"));
        objectRet.put("type",JST_BEAT);
        objectRet.put("sn",object.get("sn"));
        objectRet.put("res",GPR_SUCESS);
        objectRet.put("rtc",getGUID());
        log.info(" Heartbeat 返回给设备数据: " + objectRet);
        return objectRet;
    }

    /********************************************************************************
    当发生关键事件时,由设备上报给服务器进行记录。
    主包	{"dut":22600938,"type":2,"sn":41143,"res":0, "code":200, "msg":"user1", "tim":1543893219}
    回包	{"dut":22600938,"type":2,"sn":41143,"res":1 }
    创建人:wp
    创建时间:2020-8-11
     ********************************************************************************/
    public JSONObject IncidentReport( JSONObject object ) {
        //设备主动上报数据,调用出入口平台接口插入开门记录数据
        JSONObject revobject = new JSONObject();
        revobject = object;
        long happenTime = new Long(revobject.get("tim").toString()+"000");
        String code = revobject.get("code").toString();//1200 卡开门成功
        String uid = revobject.get("msg").toString();//返回卡号字符串
        String mode = "200";//二维码
        String access = revobject.get("dut").toString();

        Map<String, String> params = new HashMap<>();
        String data ="";

        if(code.equalsIgnoreCase("0") || code.equalsIgnoreCase("1200") || code.equalsIgnoreCase("200")
          || code.equalsIgnoreCase("3200") || code.equalsIgnoreCase("4000")){
            if(code.equalsIgnoreCase("0")) {
                if (uid.length() == 8) {
                    mode = "1200";//物业卡
                } else {
                    mode = "200";//二维码
                }
            }else {
                if(code.equalsIgnoreCase("1200")) {//物业卡
                    uid = ReverseOrder(uid);
                }
                mode = code;
            }

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'+'08:00");
            String dateUTCStr = sdf.format(happenTime);
            params.put("access", access);
            params.put("uid", uid);
            params.put("mode", mode);
            params.put("date", dateUTCStr);
            data = HttpClient.httpPostRequest(serviceIp + "/web/opensuccess/interface", JSONObject.toJSONString(params));
            JSONObject retobject = JSONObject.parseObject(data);
            if ("OK".equals(retobject.get("ret").toString())){
                log.info(" 蓝筹 上报开门记录 成功!");
            }else {
                log.error(" hardware_num:" + revobject.get("dut").toString() +" data:" + data);
            }
            log.info(" IncidentReport 上报开门记录 params: " + params);
        }else if(code.equalsIgnoreCase("1400") || code.equalsIgnoreCase("400")
            || code.equalsIgnoreCase("3400") ){
            if(code.equalsIgnoreCase("1400") && access.length()>8) {//人脸设备需要物业卡反转一次
                uid = ReverseOrder(uid);
            }
            params.put("access", access);
            params.put("uid", uid);
            params.put("mode", code);
            data = HttpClient.httpPostRequest(serviceIp + "/web/qrcode/interface", JSONObject.toJSONString(params));
            JSONObject retobject = JSONObject.parseObject(data);
            if ("OK".equals(retobject.get("ret").toString())){
                int ret = RemoteCommand(access,"open");
                log.info(" 蓝筹 主动上报在线开门上记录 成功! ret: " + ret);
            }else {
                log.error(" hardware_num:" + revobject.get("dut").toString() +" data:" + data);
            }
            log.info(" IncidentReport params: " + params);
        }else {
            log.error(" hardware_num:" + revobject.get("dut").toString() +" code:" + code +" revobject:" + revobject);
        }

        //根据设备上报数据返回处理结果
        JSONObject objectRet = new JSONObject();
        objectRet.put("dut",access);
        objectRet.put("type",JST_EVENT);
        objectRet.put("sn",revobject.get("sn"));
        objectRet.put("res",GPR_SUCESS);
        return objectRet;
    }

//下行通信(服务器发送给设备)
//    嵌入式设备
    /********************************************************************************
     服务器发送给设备,让设备执行具体动作
     主包	{"dut":22600938,"type":129,"sn":4343,"res":0, "cmd":"open"}
     回包	成功:{"dut":22600938,"type":129,"sn":4343,"res":1 }
            失败:{"dut":22600938,"type":129,"sn":4343,"res":2 }
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public int RemoteCommand(String dut,String cmd){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",dut);
        object.put("type",JST_CMD);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("cmd",cmd);
        log.info(" RemoteCommand: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
cmd	字符串	命令字符串	open:开门,控制器上两个继电器均动作
open1:开门1,控制器上继电器1动作
open2:开门2,控制器上继电器2动作
card_clean:清除所有存储,格式化存储器
card_destroy:销毁所有有效数据,但不格式化存储器
card_tidy:优化存储数据
res	8位整型	返回执行结果	1:成功
                            2:失败
*/
        return GPR_SUCESS;
    }

    /*********************************************************************************
     新增卡号(130)/删除卡号(131)/对比卡号(132)
     通过此组指令,可以将实际的授权名单下发到控制器设备进行存储,当有ID卡被识别时,控制器设备将读取到的卡号和自己存储的卡号进行对比,对比成功则授权开门。
     一个通信包,包含的卡号数目不应大于40条或字符串长度不应该大于1442字节,两者取小值,实测存储20条所消耗的时间大约在400ms。
     本通信过程为同步执行过程,一条指令未返回结果时,无法支持后续指令。
     主包	{"dut":22600938,"type":130,"sn":13930,"res":0, "list":["FB8923"," FB8924"," FB8925"],"expire":
     1565235619}
     回包	{"dut":22600938,"type":130,"sn":13930,"res":1,"suc":[" FB8923"," FB8924"," FB8925"],"faild":[]}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public int CardOperation(String dut,int type, List <String> cardlist, String expire){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",dut);
        object.put("type",type);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("list",cardlist);
        object.put("expire",expire);
        log.info(" CardOperation: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
list	字符串数组	存放ID卡号	实际的ID卡号,用于刷卡操作,每个卡号不能超过22个字符
expire	整型	过期时间
suc	    字符串数组	存放ID卡号	操作成功的卡号,比如存储成功的卡号,删除成功的卡号,对比成功的卡号(有授权的卡号)。
faild	字符串数组	存放ID卡号	操作失败的卡号
res	8位整型	返回执行结果	1:成功
                            2:失败
                            3:传入的参数有误
*/


        return GPR_SUCESS;
    }
    /********************************************************************************
     新增用户标识(133)/删除用户标识(134)/对比用户标识(135)
     通过此组指令,可以将实际的授权名单下发到控制器设备进行存储,当有二维码被识别时,控制器设备将读取到的用户标识和自己存储的用户标识进行对比,对比成功则授权开门。
     一个通信包,包含的用户字符串数目不应大于40条,字符串长度不应该大于1442字节,实测存储20条所消耗的时间大约在400ms。
     本通信过程为同步执行过程,一条指令未返回结果时,无法支持后续指令。
     主包	{"dut":22600938,"type":133,"sn":13930,"res":0, "list":["user1","user2","user3"],"expire":1565235619}
     回包	{"dut":22600938,"type":133,"sn":13930,"res":1,"suc":["user1","user2","user3"],"faild":[]}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public int UserOperation(String dut,int type, List <String> cardlist, String expire){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();

        object.put("dut",dut);
        object.put("type",type);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("list",cardlist);
        object.put("expire",expire);
        log.info(" UserOperation: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
list	字符串数组	存放用户标识字符串	实际的用户标识(如手机号,身份证号等等),用于刷二维码操作,详见二维码生成规则:“基于用户标识的动态二维码”
expire	整型	    过期时间
suc	    字符串数组	存放用户标识字符串	操作成功的用户标识,比如存储成功的用户标识,删除成功的用户标识,对比成功的用户标识(有授权的用户)。
faild	字符串数组	存放用户标识字符串	操作失败的用户标识
res	8位整型	返回执行结果	1:成功
                            2:失败
                            3:传入的参数有误
*/
        return GPR_SUCESS;
    }

    /********************************************************************************
     统计存储情况(136)
     通过此组指令,可以得到存储数据情况
     主包	{"dut":22600938,"type":136,"sn":13930,"res":0}
     回包	{"dut":22600938,"type":136,"sn":13930,"res":1,"occ":1007,"vad":991,"idl":130065}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public  int StatisticsStorage(String dut,int type){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",dut);
        object.put("type",type);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        log.info(" StatisticsStorage: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
occ	32位整型	占用空间	包括有效数据,和已删除数据的总数
vad	32位整型	有效记录数	有效的记录的总数
idl	32位整型	空闲可用记录数	可用的空闲的记录数
res	8位整型	返回执行结果	1:成功
                            2:失败
                            3:传入的参数有误
*/
        return GPR_SUCESS;
    }

    /********************************************************************************
     Android设备新增用户(150)/删除用户(151)
     通过此组指令,可以将用户信息下发到Android设备进行存储,当有人脸或卡被识别时,Android设备将读取到信息和自己存储的信息进行对比,对比成功则授权开门。
     一个通信包,包含的卡号数目不应大于10条。
     主包	{"dut":22600938,"type":150,"sn":13930,"res":0,"list":[
     {"uid":"65312","name":"张三","oid":"3564","org":"武汉蓝筹科技有限公司","dept":"研发部","img":"https://oss.aliyun.com/face1.png","card":"AF5624","expire":1565235619}
     }
     回包	{"dut":22600938,"type":150,"sn":13930,"res":1,"suc":["65312"],"faild":[]}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public  int AndroidUserOperation(String dut,int type, List <Map<String, Object>> userlist){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",Long.parseLong(dut));
        object.put("type",type);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("list",userlist);
        log.info(" AndroidUserOperation: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
list	对象数组	存放用户ID、姓名、公司ID、公司名称、部门名称、人脸图片地址、卡号、过期时间
suc	    字符串数组	存放用户ID	操作成功的用户ID
faild	字符串数组	存放用户ID	操作失败的用户ID
res	8位整型	返回执行结果	1:成功
                            2:失败
                            3:传入的参数有误
                            */
        return GPR_SUCESS;
    }

    /********************************************************************************
     删除公司(160)
     通过此组指令,可以将公司ID下发到Android设备,Android设备将设备中存储的该公司所有用户的人脸和卡数据删除。
     主包	{"dut":22600938,"type":160,"sn":13930,"res":0,"oid":"8463"}
     回包	{"dut":22600938,"type":160,"sn":13930,"res":1}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public  int DeleteCompany(String dut,String oid){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",dut);
        object.put("type",JST_ANDROID_DEL_ORG);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("oid",oid);
        log.info(" DeleteCompany: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
oid	字符串	存放公司ID
res	8位整型	返回执行结果	1:成功
                            2:失败
                            3:传入的参数有误
*/
        return GPR_SUCESS;
    }

    /********************************************************************************
     程序升级(170)
     通过此组指令,可以将新版本app下载地址发到Android设备,Android下载完成后静默升级.
     主包	{"dut":22600938,"type":170,"sn":13930,"res":0,"ver":"20190531","url":"http://www.baidu.com","tim":1543893219}
     回包	{"dut":22600938,"type":170,"sn":13930,"res":1}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public  int ProgramUpgrade(String dut,String ver,String url,String tim){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",dut);
        object.put("type",JST_ANDROID_APP_UPGRADE);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("ver",ver);
        object.put("url",url);
        object.put("tim",tim);
        log.info(" ProgramUpgrade: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
ver	字符串	版本号	0  = 取消升级
url	字符串	下载地址
tim	整型	更新时间
res	8位整型	返回执行结果	1:成功
                            2:正在下载中
                            3:传入的参数有误
                            4:版本号过期
*/
        return GPR_SUCESS;

    }

    /********************************************************************************
     提取设备日志(180)
     通过此组指令,可以告知设备APP服务端需要提取设备日志。
     主包	{"dut":22600938,"type":180,"sn":13930,"res":0,"date":"2020-06-30",”logtype”:1}
     回包	{"dut":22600938,"type":180,"sn":13930,"res":1}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public  int ExtractDeviceLogs(String dut,String date,String logtype){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",dut);
        object.put("type",JST_ANDROID_GET_LOG);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("date",date);
        object.put("logtype",logtype);
        log.info(" ExtractDeviceLogs: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
ver	字符串	版本号	0  = 取消升级
url	字符串	下载地址
tim	整型	更新时间
res	8位整型	返回执行结果	1:成功
                            2:正在下载中
                            3:传入的参数有误
                            4:版本号过期
*/
        return GPR_SUCESS;
    }

    /********************************************************************************
     视频通话(190)
     通过此组指令,可以通知安卓设备启动视频通话功能.
     主包	{"dut":22600938,"type":190,"sn":13930,"res":0,"channel":"123456789"}
     回包	{"dut":22600938,"type":190,"sn":13930,"res":1}
     创建人:wp
     创建时间:2020-8-11
     ********************************************************************************/
    public int VideoCall(String dut,String channel){
        //服务器发送给设备,让设备执行具体动作。
        JSONObject object = new JSONObject();
        object.put("dut",dut);
        object.put("type",JST_ANDROID_VIDEO);
        object.put("sn",getGUID());
        object.put("res",GPR_MAIN);
        object.put("channel",channel);
        log.info(" VideoCall: " + object.toString());

        BlueChipsServerHandler blueChipsServerHandler = new BlueChipsServerHandler();
        try {
            return blueChipsServerHandler.sendMsg(dut,object.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
/*
channel	字符串	手机号(频道号)
res	8位整型	返回执行结果	1:成功
                            2:失败
*/
        return GPR_SUCESS;
    }
}

完整代码详细见https://download.csdn.net/download/weixin_42575806/12832096

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗亚方舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值