终端参数上报后,平台通过tcp协议接收到相应数据并处理。

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

实现流程如下。

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

《终端参数上报后,平台通过tcp协议接收到相应数据并处理。》
《终端参数上报后,平台通过tcp协议接收到相应数据并处理。》

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":错误码
}

 

点赞