南昌市物联网技防平台-后台
Administrator
2021-03-04 a08f28be2302ce139aecb34765296e2b47afd129
体温数据插入
4 files modified
6 files added
461 ■■■■■ changed files
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/JfptApplication.java 6 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/MyNettyDecode.java 126 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/NettyConstant.java 12 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/NettyProPool.java 53 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/ParseString.java 14 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/TcpServer.java 92 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/TcpServerHandler.java 105 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyUdpServer/entity/BladeAnimalHeat.java 4 ●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyUdpServer/service/AnimalHeatService.java 10 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyUdpServer/service/impl/AnimalHeatServiceImpl.java 39 ●●●●● patch | view | raw | blame | history
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/JfptApplication.java
@@ -19,6 +19,7 @@
import org.springblade.core.cloud.feign.EnableBladeFeign;
import org.springblade.core.launch.BladeApplication;
import org.springblade.jfpt.nettyServer.Server;
import org.springblade.jfpt.nettyTcpServer.TcpServer;
import org.springblade.jfpt.nettyUdpServer.server.UdpServer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -39,8 +40,9 @@
    @Override
    public void run(String... args) throws Exception {
        Server server=new Server(8088);
        UdpServer udpServer=new UdpServer(8099);
        //Server server=new Server(8088);
        TcpServer server=new TcpServer(8088);
        //UdpServer udpServer=new UdpServer(8099);
    }
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/MyNettyDecode.java
New file
@@ -0,0 +1,126 @@
package org.springblade.jfpt.nettyTcpServer;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
/**
 * 自定义解码器
 *
 */
public class MyNettyDecode extends ByteToMessageDecoder {
    public final int BASE_LENGTH = 4 + 4 ;
//    @Override
//    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
//        System.out.println("byteBuf = " + byteBuf.readableBytes());
//        // 可读长度必须大于基本长度
//        if (byteBuf.readableBytes() >= BASE_LENGTH) {
//            // 防止socket字节流攻击
//            // 防止,客户端传来的数据过大
//            // 因为,太大的数据,是不合理的
//            if (byteBuf.readableBytes() > 202048) {
//                byteBuf.skipBytes(byteBuf.readableBytes());
//            }
//
//            // 记录包头开始的index
//            int beginReader;
//
//            while (true) {
//                // 获取包头开始的index
//                beginReader = byteBuf.readerIndex();
//                // 标记包头开始的index
//                byteBuf.markReaderIndex();
//                // 读到了协议的开始标志,结束while循环
//                if (byteBuf.readInt() == NettyConstant.HEAD_DATA) {
//                    break;
//                }
//
//                // 未读到包头,略过一个字节
//                // 每次略过,一个字节,去读取,包头信息的开始标记
//                byteBuf.resetReaderIndex();
//                byteBuf.readByte();
//
//                // 当略过,一个字节之后,
//                // 数据包的长度,又变得不满足
//                // 此时,应该结束。等待后面的数据到达
//                if (byteBuf.readableBytes() < BASE_LENGTH) {
//                    return;
//                }
//            }
//
//            // 消息的长度
//
//            int length = byteBuf.readInt();
//            // 判断请求数据包数据是否到齐
//            if (byteBuf.readableBytes() < length) {
//                // 还原读指针
//                byteBuf.readerIndex(beginReader);
//                return;
//            }
//
//            // 读取data数据
//            byte[] data = new byte[length];
//            byteBuf.readBytes(data);
//            System.out.println("byteBuf末尾 = " + byteBuf);
//
//            NettyProPool protocol = new NettyProPool(data.length, data);
//            list.add(protocol);
//            System.out.println("list = " + list);
//        }
//    }
    static final int PACKET_SIZE = 110088;
    // 用来临时保留没有处理过的请求报文
    ByteBuf tempMsg = Unpooled.buffer();
    /**
     * @param ctx
     * @param in 请求的数据
     * @param out 将粘在一起的报文拆分后的结果保留起来
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        System.out.println(Thread.currentThread() + "收到了一次数据包,长度是:" + in.readableBytes());
        // 合并报文
        ByteBuf message = null;
        int tmpMsgSize = tempMsg.readableBytes();
        System.out.println("tmpMsgSize = " + tmpMsgSize);
        // 如果暂存有上一次余下的请求报文,则合并
        if (tmpMsgSize > 0) {
            message = Unpooled.buffer();
            message.writeBytes(tempMsg);
            message.writeBytes(in);
            System.out.println("合并:上一数据包余下的长度为:" + tmpMsgSize + ",合并后长度为:" + message.readableBytes());
        } else {
            message = in;
        }
        int size = message.readableBytes();
        int counter = size / PACKET_SIZE;
        for (int i = 0; i < counter; i++) {
            byte[] request = new byte[PACKET_SIZE];
            // 每次从总的消息中读取220个字节的数据
            message.readBytes(request);
            // 将拆分后的结果放入out列表中,交由后面的业务逻辑去处理
            out.add(Unpooled.copiedBuffer(request));
        }
        // 多余的报文存起来
        // 第一个报文: i+  暂存
        // 第二个报文: 1 与第一次
        size = message.readableBytes();
        if (size != 0) {
            System.out.println("多余的数据长度:" + size);
            // 剩下来的数据放到tempMsg暂存
            tempMsg.clear();
            tempMsg.writeBytes(message.readBytes(size));
        }
    }
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/NettyConstant.java
New file
@@ -0,0 +1,12 @@
package org.springblade.jfpt.nettyTcpServer;
/**
 * 自定义协议常量
 */
public class NettyConstant {
    /**
     * 自定义协议开始
     */
    public static final int HEAD_DATA = 0*76;
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/NettyProPool.java
New file
@@ -0,0 +1,53 @@
package org.springblade.jfpt.nettyTcpServer;
public class NettyProPool {
    /**
     * 协议开始的标志,16进制为 0*76
     */
    private int haed_data=NettyConstant.HEAD_DATA;
    /**
     * 传送的长度
     */
    private int contentLength;
    /**
     * 传送的内容
     */
    private byte[] content;
    public NettyProPool(int contentLength) {
        this.contentLength = contentLength;
    }
    public int getContentLength() {
        return contentLength;
    }
    public void setContentLength(int contentLength) {
        this.contentLength = contentLength;
    }
    public NettyProPool(int contentLength, byte[] content) {
        this.contentLength = contentLength;
        this.content = content;
    }
    public byte[] getContent() {
        return content;
    }
    public void setContent(byte[] content) {
        this.content = content;
    }
    public int getHaed_data() {
        return haed_data;
    }
    public void setHaed_data(int haed_data) {
        this.haed_data = haed_data;
    }
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/ParseString.java
New file
@@ -0,0 +1,14 @@
package org.springblade.jfpt.nettyTcpServer;
import io.swagger.models.auth.In;
public class ParseString {
        public static Integer[] stringToInts(String s){
            String[] split = s.split(",");
            Integer[] n = new Integer[split.length];
            for(int i = 0;i<split.length;i++){
                n[i] = Integer.parseInt(split[i]);
            }
            return n;
        }
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/TcpServer.java
New file
@@ -0,0 +1,92 @@
package org.springblade.jfpt.nettyTcpServer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LoggingHandler;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
public class TcpServer {
    private int port;
    private ServerSocketChannel serverSocketChannel;
    public TcpServer(int port){
        this.port = port;
        bind();
    }
    private void bind() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //服务端要建立两个group,一个负责接收客户端的连接,一个负责处理数据传输
                //连接处理group
                EventLoopGroup boss = new NioEventLoopGroup();
                //事件处理group
                EventLoopGroup worker = new NioEventLoopGroup();
                ServerBootstrap bootstrap = new ServerBootstrap();
                // 绑定处理group
                bootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
                    //保持连接数
                    .option(ChannelOption.SO_BACKLOG, 128)
                    //有数据立即发送
                    .option(ChannelOption.TCP_NODELAY, true)
                    //保持连接
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(512*250))
                    .childHandler(new NettyChannelHandler());
                //绑定端口,同步等待成功
                ChannelFuture future;
                try {
                    future = bootstrap.bind(port).sync();
                    if (future.isSuccess()) {
                        serverSocketChannel = (ServerSocketChannel) future.channel();
                        System.out.println("服务端启动成功,端口:"+port);
                    } else {
                        System.out.println("服务端启动失败!");
                    }
                    //等待服务监听端口关闭,就是由于这里会将线程阻塞,导致无法发送信息,所以我这里开了线程
                    future.channel().closeFuture().sync();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                finally {
                    //优雅地退出,释放线程池资源
                    boss.shutdownGracefully();
                    worker.shutdownGracefully();
                }
            }
        });
        thread.start();
    }
    private class NettyChannelHandler extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel socketChannel)
            throws Exception {
            //socketChannel.pipeline().addLast(new MyNettyDecode());
            //socketChannel.pipeline().addLast(new StringDecoder(Charset.forName("UTF-8")));
            //socketChannel.pipeline().addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
            //socketChannel.pipeline().addLast("encoder", new LengthFieldPrepender(4, false));
            socketChannel.pipeline().addLast(new TcpServerHandler());
        }
    }
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyTcpServer/TcpServerHandler.java
New file
@@ -0,0 +1,105 @@
package org.springblade.jfpt.nettyTcpServer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springblade.jfpt.alarm.service.IAlarmService;
import org.springblade.jfpt.equipment.service.IEquipmentService;
import org.springblade.jfpt.nettyServer.NettyConfig;
import org.springblade.jfpt.nettyUdpServer.service.AnimalHeatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class TcpServerHandler extends ChannelInboundHandlerAdapter {
    private  String reg_LA ="LA[d]{8}[d|A-F]{12}[d|A-F]{8}[d|A-Z]{2}[d|A-F]{4}[x2A][d|A-F]{6}[#@]";
    private String reg_LB = "LB[\\d|A-F]{12}[\\x2A].*[#@]";
    private String reg_LB2 = "LB[\\d|A-F]{6}[\\x2A].*[#@]";
    private String reg_LD = "LD[d]{8}[d|A-F]{12}:[A-Z]{4}[\\x2A].*[#@]";
    private ConcurrentHashMap<String, Channel> sessionChannelMap = new ConcurrentHashMap<String, Channel>();
    @Autowired
    private org.springblade.jfpt.catalog.service.catalogService catalogService;
    @Autowired
    private org.springblade.jfpt.Netty.service.nettyService nettyService;
    @Autowired
    private IEquipmentService equipmentService;
    @Autowired
    private IAlarmService alarmService;
    private static TcpServerHandler tcpServerHandler;
    @Autowired
    private AnimalHeatService animalHeatService;
    @PostConstruct
    public void init() {
        tcpServerHandler = this;
    }
    /**
     * 客户端与服务端创建连接的时候调用
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("CTX:"+ctx.channel());
        System.out.println("客户端与服务端连接开始...");
//        ChannelId id = ctx.channel().id();
//        String s = id.toString();
        //NettyConfig.group.add(ctx.channel());
    }
    /**
     * 客户端与服务端断开连接时调用
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端与服务端连接关闭...");
        NettyConfig.group.remove(ctx.channel());
    }
    /**
     * 服务端接收客户端发送过来的数据结束之后调用
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
        System.out.println("信息接收完毕...");
    }
    /**
     * 工程出现异常的时候调用
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
    /**
     * 服务端处理客户端websocket请求的核心方法,这里接收了客户端发来的信息
     */
    @Override
    public void channelRead(ChannelHandlerContext channelHandlerContext, Object info) throws Exception {
        System.out.println("接收到了:"+info);
        ByteBuf buf = (ByteBuf) info;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        String content = body;
        System.out.println("接收客户端数据:" + body);
        //插入数据
        tcpServerHandler.animalHeatService.save(body);
    }
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyUdpServer/entity/BladeAnimalHeat.java
@@ -37,10 +37,10 @@
    private Float tempRed;// float(4,2) DEFAULT NULL COMMENT '当前人员的温度',
    @TableField("person_rect")
    private String personRect;// varchar(63) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '人脸位置二位数组,[left,top,right,bottom]',
    private String[] personRect;// varchar(63) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '人脸位置二位数组,[left,top,right,bottom]',
    @TableField("person_rect_red")
    private String personRectRed;// varchar(63) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '红外人脸位置二位数组,[left,top,right,bottom]',
    private Integer[] personRectRed;// varchar(63) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '红外人脸位置二位数组,[left,top,right,bottom]',
    @TableField("create_time")
    private Date createTime;// datetime DEFAULT NULL COMMENT '创建时间',
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyUdpServer/service/AnimalHeatService.java
@@ -1,7 +1,15 @@
package org.springblade.jfpt.nettyUdpServer.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springblade.jfpt.nettyUdpServer.entity.BladeAnimalHeat;
/**
 * 体温监测服务层接口层
 */
public interface AnimalHeatService {
public interface AnimalHeatService extends IService<BladeAnimalHeat> {
    /**
     * 插入体温数据
     * @param body 温度数据
     */
    void save(String body);
}
blade-service/blade-jfpts/src/main/java/org/springblade/jfpt/nettyUdpServer/service/impl/AnimalHeatServiceImpl.java
@@ -1,12 +1,22 @@
package org.springblade.jfpt.nettyUdpServer.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.jfpt.nettyTcpServer.ParseString;
import org.springblade.jfpt.nettyUdpServer.entity.BladeAnimalHeat;
import org.springblade.jfpt.nettyUdpServer.mapper.AnimalHeatMapper;
import org.springblade.jfpt.nettyUdpServer.service.AnimalHeatService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Array;
import java.util.Map;
import static org.springblade.core.tool.utils.DateUtil.now;
/**
 * 体温数据服务层
 *
 */
@Service
public class AnimalHeatServiceImpl extends ServiceImpl<AnimalHeatMapper, BladeAnimalHeat> implements AnimalHeatService {
    @Override
@@ -14,4 +24,33 @@
        return false;
    }
    /**
     * 新增体温数据
     * @param body 体温数据
     */
    @Override
    @Transactional
    public void save(String body) {
        //1.截取信息
        int i = body.indexOf("{");
        //2.从 {  处开始截取
        int length = body.length();
        //3.截取
        String dataBody = body.substring(i, length);
        System.out.println("dataBody = " + dataBody);
        //4.数据转换
        Map<String,Object> data = (Map<String, Object>) JSONObject.parse(dataBody);
        System.out.println("data = " + data);
        //5.创建体温数据对象
        BladeAnimalHeat bladeAnimalHeat = new BladeAnimalHeat();
        //6.取出数据,封装数据到对象
        bladeAnimalHeat.setPicture(data.get("picture").toString());
        String temp_red =data.get("temp_red").toString();
        bladeAnimalHeat.setTempRed(Float.parseFloat(temp_red.substring(1,temp_red.length()-1)));
        String person_rects = data.get("person_rect").toString();
        bladeAnimalHeat.setPersonRect(person_rects.substring(2,person_rects.length()-2).split(","));
        bladeAnimalHeat.setCreateTime(now());
        //7.插入数据
        int idata = baseMapper.insert(bladeAnimalHeat);
    }
}