更新时间:2024-07-29 GMT+08:00
分享

代码开发

准备工作

  • 开发环境要求:已经安装JDK(版本1.8.以上)和maven。
  • 已下载泛协议SDK和样例。

项目结构说明

项目结构说明

图1 项目结构图
表1 类相关说明

类名称

描述

Main

主启动类。

BridgeService

网桥初始化:初始化同IoT平台的连接,设置平台下行数据监听

TcpServer

TCP协议服务端启动类。开启TCP协议监听端口,接收设备上报到服务端的消息。

MessageDecoder

上行数据的消息解码,将TCP原始码流转换为具体JSON对象。

MessageEncoder

下行数据的消息编码,将对象数据转换为TCP原始码流。

UpLinkHandler

设备上行数据处理类。把TCP协议数据转成平台格式数据,并调用SDK接口进行上报

DownLinkHandler

IoT平台下发数据处理类。将平台下发数据转换为TCP协议数据,并下发给设备。

DeviceSessionManger

设备会话管理。管理设备同服务端的连接。

初始化网桥SDK

创建BridgeBootstrap对象实例,调用initBridge方法,在该方法中会读取环境变量的配置信息,并同IoT平台建立网桥连接。

环境变量说明:

表2 环境变量说明

环境变量名称

参数说明

样例

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();
}

相关文档