终端参数上报后,平台通过tcp协议接收到相应数据并处理。
终端将终端参数以json格式的数据发送至平台。终端上电后上报,可以不认证直接上报。
实现流程如下。
1.设置终端参数上报的协议类型,例如:0x0000。
1 public static final int CMD_UP_PARAM = 0x0000;
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":错误码 }