zoukankan      html  css  js  c++  java
  • 终端参数上报后,平台通过tcp协议接收到相应数据并处理。

    终端将终端参数以json格式的数据发送至平台。终端上电后上报,可以不认证直接上报。

    实现流程如下。

    1.设置终端参数上报的协议类型,例如:0x0000。

    1 public static final int CMD_UP_PARAM = 0x0000;
    View Code

    2.侦听tcp服务

     1 public void startServer() {
     2         log.info("startServer begin,tcp port={}", port);
     3         //处理接收accept连接的线程池
     4         EventLoopGroup bossGroup = new NioEventLoopGroup();
     5         //处理tcp接收到的数据的线程池
     6         EventLoopGroup workerGroup = new NioEventLoopGroup();
     7         try {
     8             ServerBootstrap b = new ServerBootstrap();
     9             b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
    10             b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);// 关键是这句
    11             b.group(bossGroup, workerGroup)
    12                     .channel(NioServerSocketChannel.class)
    13                     .childHandler(new ChannelInitializer<SocketChannel>() {
    14                         @Override
    15                         public void initChannel(SocketChannel ch)
    16                                 throws Exception {
    17                             
    18                             InetSocketAddress insocket = (InetSocketAddress)ch.localAddress();
    19                             // 注册OutboundHandler,执行顺序为注册顺序的逆序
    20                             ch.pipeline().addLast(new ProtocolEncoder());
    21                             // 注册InboundHandler,执行顺序为注册顺序
    22                             //tcp连接始终  120秒 没收到数据 300毫秒未发送数据
    23                             ch.pipeline().addLast(new IdleStateHandler(120000, 0, 0, TimeUnit.MILLISECONDS));
    24                             //根据不同的侦听端口,采用不同的解码类
    25                             ch.pipeline().addLast(new ProtocolDecoder());
    26                             ch.pipeline().addLast(new DiffChannelLogin());
    27                             ch.pipeline().addLast(new DealProtocolData());
    28 
    29                         }
    30 
    31                     }).option(ChannelOption.SO_BACKLOG, 128)
    32                     .childOption(ChannelOption.SO_KEEPALIVE, true);
    33             log.info("startServer bind,tcp port={}", port);
    34             ChannelFuture f = b.bind(port).sync();
    35             f.channel().closeFuture().sync();
    36         } catch (InterruptedException e) {
    37             log.error("InterruptedException e={}", e);
    38         } finally {
    39             workerGroup.shutdownGracefully();
    40             bossGroup.shutdownGracefully();
    41             log.info("startServer end,tcp port={}", port);
    42         }
    43     }

    3.处理接收到的tcp数据,该数据是登录认证后的数据。

    处理完成后,将结果响应给终端。4位处理代码。

     1 ProtDataApi diffProtocol(ChnlData chl, ProtDataApi protData) {
     2         if (protData instanceof ProtDataString) {//instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
     3             return diffProtocolString(chl, protData);
     4         }
     5         
     6         ProtData data = (ProtData) protData; 
     7         //log.info("diffProtocol,json={}", data.jsontext);
     8         JSONObject json = JSON.parseObject(data.jsontext);
     9         JSONObject res = null;
    10         
    11         if (data.getCmd() == DeviceProtCmd.CMD_UP_LOGIN) {
    12             res = service.logIn(chl, json);
    13             if (res == null) {
    14                 chl.close();
    15                 return null;
    16             }
    17         } else if(data.getCmd() == DeviceProtCmd.CMD_UP_PARAM){
    18             
    19         } else if (chl.getData() instanceof DeviceData == false){
    20             chl.close();
    21             return null;
    22         } 
    23         
    24         long context = json.getLongValue("context");
    25         if (context > 0) {
    26             
    27         }
    28         
    29         taskDao.recvDevTaskData(data.getCmd(), json);
    30         
    31         DeviceData dev = (DeviceData) chl.getData();
    32         if (dev != null) {
    33             ProtDataApi d = dao.updateTaskFlag(dev.getId(), json);
    34             if (d != null) {
    35                 return d;
    36             }
    37         }
    38 switch (data.getCmd()) {
    39 case DeviceProtCmd.CMD_UP_PARAM:
    40             res = service.uploadParam(chl, json);
    41             break;
    42 default:
    43             break;
    44         }
    45         
    46         if (res == null) {
    47             return null;
    48         }
    49         
    50         return new ProtData(data.getCmd(), data.getSessionId(), res.toJSONString(), chl.getEncoding());
    51     }

    4.平台处理接收到的终端参数,并更新入库,响应结果。

    public JSONObject uploadParam(JSONObject json) throws Exception {
            String identity = json.getString("identity");// ”:”设备序列号”, 
            int id = dataDao.getDeviceId(identity);
            if (id == -1) {
                log.error("该设备,identity={},不存在!", identity);
                return JsonUtils.getErrorJson(ErrorCode.ERR_NORECORD);
            }
            
            String modelno = json.getString("modelno");//":"KCC(1A)", //设备型号
            String devtype = json.getString("devtype");//":"1011", //设备类型
            String hardver = json.getString("hardver");//":"硬件版本",
            String softver = json.getString("softver");//":"软件版本",
            String serverip = json.getString("serverip");//":"平台ip",
            String serverport = json.getString("serverport");//":"平台端口号",
            String sql = "update info_terminal set devModel=?,devicetypeid=?,hardver=?"
                    + ",softver=?,platform_ip=?,platform_port=? where id=?";
            JSONObject res;
            try {
                jt.update(sql, modelno,devtype,hardver,softver,serverip,serverport,id);
                res = JsonUtils.getErrorJson(ErrorCode.ERR_SUCCESS);
            } catch (DataAccessException e) {
                log.error("更新参数失败,sql={},json={},exception={}", sql, json.toJSONString(), e);
                res = JsonUtils.getErrorJson(ErrorCode.ERR_SAVE);
            }        
            return res;
        }

    5.回应终端数据处理

     1 public short head;//协议头
     2     public int cmd;//协议类型
     3     public int sessID;//会话id
     4     public short pkgID;//包号
     5     public short pkgCount;//总包数
     6     public short keyID;//密钥id
     7     public short datalen;//单包数据长途
     8     public int totalLen;//数据总长度
     9     public byte[] data;//数据
    10     private ChannelHandlerContext ctx;
    11     public String jsontext;//json字符串
    12     private String encoding;
    13 
    14 public ProtData(int cmd, int sessID, String jsontext, String encoding){
    15         this.encoding = encoding;
    16         this.head = 0x2324;
    17         this.cmd = cmd;
    18 
    19         this.sessID = sessID;
    20         pkgCount = 1;
    21         pkgID = 0;
    22         keyID = (short) DeskeyConfig.getKeyId();
    23         datalen = 0;
    24         data = new byte[datalen];
    25         DecryptionMode jm = DecryptionMode3DesImp.getDecryptionMode();
    26         data = jm.getDecryption(data, sessID, keyID);
    27         this.jsontext = jsontext;
    28     }

     6.附上协议。

    json格式如下:
    {
    "identity":"设备序列号", 
    "modelno":"kcc(1a)", //设备型号
    "devtype":1011, //设备类型
    "hardver":"硬件版本",
    "softver":"软件版本",
    "serverip":"平台ip",
    "serverport":平台端口号
    }
    应答:
    字段名    长度    备注
    json    n    json格式的数据
            
    json格式如下:
    {
        "errcode":错误码
    }
  • 相关阅读:
    matrix_2015_1 138
    2014ACM/ICPC亚洲区广州站 北大命题
    无向图的联通分量
    5.1 基础题目选讲
    URAL
    Codeforces Round #274 (Div. 2)
    后缀数组
    poj 1661 help jimmy dp
    hdu 1676 Full Tank? 限制最短路 dp 蛮有技巧的~
    hdu 1023 Train Problem II 双向广搜
  • 原文地址:https://www.cnblogs.com/lghao/p/11151796.html
Copyright © 2011-2022 走看看