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