代码开发
准备工作
- 开发环境要求:已经安装JDK(版本1.8.以上)和maven。
- 已下载泛协议SDK和样例。
项目结构说明
项目结构说明
类名称 |
描述 |
---|---|
Main |
主启动类。 |
BridgeService |
网桥初始化:初始化同IoT平台的连接,设置平台下行数据监听 |
TcpServer |
TCP协议服务端启动类。开启TCP协议监听端口,接收设备上报到服务端的消息。 |
MessageDecoder |
上行数据的消息解码,将TCP原始码流转换为具体JSON对象。 |
MessageEncoder |
下行数据的消息编码,将对象数据转换为TCP原始码流。 |
UpLinkHandler |
设备上行数据处理类。把TCP协议数据转成平台格式数据,并调用SDK接口进行上报 |
DownLinkHandler |
IoT平台下发数据处理类。将平台下发数据转换为TCP协议数据,并下发给设备。 |
DeviceSessionManger |
设备会话管理。管理设备同服务端的连接。 |
初始化网桥SDK
创建BridgeBootstrap对象实例,调用initBridge方法,在该方法中会读取环境变量的配置信息,并同IoT平台建立网桥连接。
环境变量说明:
环境变量名称 |
参数说明 |
样例 |
---|---|---|
NET_BRIDGE_ID |
网桥ID |
bridge001 |
NET_BRIDGE_SECRET |
网桥密钥 |
********** |
NET_BRIDGE_SERVER_IP |
IoTDA平台地址 |
*****.iot-mqtts.cn-north-4.myhuaweicloud.com |
NET_BRIDGE_SERVER_PORT |
IoTDA平台泛协议接入端口号 |
8883 |
初始化成功后,需要设置平台下行数据的监听器,监听平台的下行数据。
代码样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public void init() { //网桥启动初始化 BridgeBootstrap bridgeBootstrap = new BridgeBootstrap(); // 从环境变量获取配置进行初始化 bridgeBootstrap.initBridge(); bridgeClient = bridgeBootstrap.getBridgeDevice().getClient(); // 设置平台下行数据监听器 DownLinkHandler downLinkHandler = new DownLinkHandler(); bridgeClient.setBridgeCommandListener(downLinkHandler) // 设置平台命令下发监听器 .setBridgeDeviceMessageListener(downLinkHandler) // 设置平台消息下发监听器 .setBridgeDeviceDisConnListener(downLinkHandler); // 设置平台通知网桥主动断开设备连接的监听器 } |
设备登录上线
设备登录上线的实现样例如下:
1 2 3 4 5 6 7 8 9 10 11 |
private void login(Channel channel, DeviceLoginMessage message) { int resultCode = BridgeService.getBridgeClient().loginSync(deviceId, secret, 5000); // 登录成功保存会话信息 if (resultCode == 0) { deviceSession.setDeviceId(deviceId); deviceSession.setChannel(channel); DeviceSessionManger.getInstance().createSession(deviceId, deviceSession); NettyUtils.setDeviceId(channel, deviceId); } } |
设备上线时,需要从原始设备消息中解析出鉴权信息(设备ID和密钥),再调用SDK提供的login接口向平台发起登录请求,平台收到设备的login请求后,会对设备的鉴权信息进行认证,认证通过后会通过返回码告知网桥SDK设备的登录结果。您需要根据登录结果对设备进行记录会话信息、给设备返回响应等处理。
设备数据上报
设备登录成功后,收到设备的上行数据时,可调用SDK的reportProperties将解码后的数据上报到IoT平台。
代码样例参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private void reportProperties(Channel channel, BaseMessage message) { String deviceId = message.getMsgHeader().getDeviceId(); DeviceSession deviceSession = DeviceSessionManger.getInstance().getSession(deviceId); if (deviceSession == null || !deviceSession.isLoginSuccess()) { log.warn("device={} is not login", deviceId); sendResponse(channel, message, 1); return; } // 调用网桥reportProperties接口,上报设备属性数据 BridgeService.getBridgeClient() .reportProperties(deviceId, Collections.singletonList(serviceProperty), new ActionListener() { @Override public void onSuccess(Object context) { sendResponse(channel, message, 0); } @Override public void onFailure(Object context, Throwable var2) { log.warn("device={} reportProperties failed: {}", deviceId, var2.getMessage()); sendResponse(channel, message, 1); } }); } |
平台指令下发
网桥在初始化时向SDK注册了BridgeCommandListener的监听。当有下行指令时,网桥SDK就会回调BridgeCommandListener的onCommand方法。您可在onCommand中对平台的下行指令进行处理。
代码样例参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void onCommand(String deviceId, String requestId, BridgeCommand bridgeCommand) { log.info("onCommand deviceId={}, requestId={}, bridgeCommand={}", deviceId, requestId, bridgeCommand); DeviceSession session = DeviceSessionManger.getInstance().getSession(deviceId); if (session == null) { log.warn("device={} session is null", deviceId); return; } // 设置位置上报的周期 if (Constants.MSG_TYPE_FREQUENCY_LOCATION_SET.equals(bridgeCommand.getCommand().getCommandName())) { processLocationSetCommand(session, requestId, bridgeCommand); } } |
设备离线
网桥检查到设备到服务端的长连接断开时,需要调用SDK的logout接口通知平台设备离线。
代码样例参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void channelInactive(ChannelHandlerContext ctx) throws Exception { String deviceId = NettyUtils.getDeviceId(ctx.channel()); DeviceSessionManger.getInstance().getSession(deviceId); if (deviceId == null) { return; } // 调用网桥的logout接口,通知平台设备离线 DefaultActionListenerImpl defaultLogoutActionListener = new DefaultActionListenerImpl("logout"); BridgeService.getBridgeClient().logout(deviceId, UUID.randomUUID().toString(), defaultLogoutActionListener); DeviceSessionManger.getInstance().deleteSession(deviceId); ctx.close(); } |