【问题标题】:How to detect weather the endpoint (KAA SDK) is connected to KAA server or not from application如何检测端点(KAA SDK)是否从应用程序连接到KAA服务器的天气
【发布时间】:2016-10-26 04:40:06
【问题描述】:

是否有任何机制或方法或步骤来检测应用程序与 KAA 服务器的端点(KAA SDK)连接。

如果不是,那我们如何远程识别故障设备?或者在现场部署设备后,我们如何识别无法与 KAA 服务器通信的设备??

如何实现这一要求来释放物联网的力量?

【问题讨论】:

    标签: kaa


    【解决方案1】:

    如果您的端点在连接到 Kaa 服务器时遇到一些问题,则会发生“故障转移”。

    因此,您必须定义自己的故障转移策略并为您的 Kaa 客户端设置它。每次发生故障转移时,都会调用策略的onFialover() 方法。

    您可以在下面看到 Java SDK 的代码示例。

      import org.kaaproject.kaa.client.DesktopKaaPlatformContext;
      import org.kaaproject.kaa.client.Kaa;
      import org.kaaproject.kaa.client.KaaClient;
      import org.kaaproject.kaa.client.SimpleKaaClientStateListener;
      import org.kaaproject.kaa.client.channel.failover.FailoverDecision;
      import org.kaaproject.kaa.client.channel.failover.FailoverStatus;
      import org.kaaproject.kaa.client.channel.failover.strategies.DefaultFailoverStrategy;
      import org.kaaproject.kaa.client.exceptions.KaaRuntimeException;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
    
      import java.io.IOException;
      import java.util.concurrent.TimeUnit;
    
      /**
      * A demo application that shows how to use the Kaa credentials API.
      */
      public class CredentialsDemo {
      private static final Logger LOG = LoggerFactory.getLogger(CredentialsDemo.class);
      private static KaaClient kaaClient;
    
      public static void main(String[] args) throws InterruptedException, IOException {
    
      LOG.info("Demo application started");
    
      try {
    
      // Create a Kaa client and add a startup listener
      kaaClient = Kaa.newClient(new DesktopKaaPlatformContext(), new SimpleKaaClientStateListener() {
      @Override
      public void onStarted() {
      super.onStarted();
      LOG.info("Kaa client started");
      }
      }, true);
    
      kaaClient.setFailoverStrategy(new CustomFailoverStrategy());
      kaaClient.start();
    
      // ... Do some work ...
    
      LOG.info("Stopping application.");
      kaaClient.stop();
    
      } catch (KaaRuntimeException e) {
      LOG.info("Cannot connect to server - no credentials found.");
      LOG.info("Stopping application.");
      }
    
      }
    
      // Give a possibility to manage device behavior when it loses connection
      // or has other problems dealing with Kaa server.
      private static class CustomFailoverStrategy extends DefaultFailoverStrategy {
    
      @Override
      public FailoverDecision onFailover(FailoverStatus failoverStatus) {
      LOG.info("Failover happen. Failover type: " + failoverStatus);
    
      // See enum DefaultFailoverStrategy from package org.kaaproject.kaa.client.channel.failover
      // to list all possible values
      switch (failoverStatus) {
      case CURRENT_BOOTSTRAP_SERVER_NA:
      LOG.info("Current Bootstrap server is not available. Trying connect to another one.");
    
      // ... Do some recovery, send notification messages, etc. ...
    
      // Trying to connect to another bootstrap node one-by-one every 5 seconds
      return new FailoverDecision(FailoverDecision.FailoverAction.USE_NEXT_BOOTSTRAP, 5L, TimeUnit.SECONDS);
      default:
      return super.onFailover(failoverStatus);
      }
      }
      }
      }
    

    更新(2016 年 10 月 28 日)

    服务器端,您可以检查端点凭据状态,如下面代码中的方法checkCredentialsStatus() 所示。状态IN_USE 表明端点至少有一次成功的连接尝试。

    不幸的是,在当前的 Kaa 版本中,没有办法直接检查端点是否连接到服务器。我在代码示例之后描述它们。

      package org.kaaproject.kaa.examples.credentials.kaa;
    
      import org.kaaproject.kaa.common.dto.ApplicationDto;
      import org.kaaproject.kaa.common.dto.admin.AuthResultDto;
      import org.kaaproject.kaa.common.dto.credentials.CredentialsStatus;
      import org.kaaproject.kaa.examples.credentials.utils.IOUtils;
      import org.kaaproject.kaa.server.common.admin.AdminClient;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
    
      import java.util.List;
    
      public class KaaAdminManager {
    
      private static final Logger LOG = LoggerFactory.getLogger(KaaAdminManager.class);
    
      private static final int DEFAULT_KAA_PORT = 8080;
      private static final String APPLICATION_NAME = "Credentials demo";
    
      public String tenantAdminUsername = "admin";
      public String tenantAdminPassword = "admin123";
    
      private AdminClient adminClient;
    
      public KaaAdminManager(String sandboxIp) {
      this.adminClient = new AdminClient(sandboxIp, DEFAULT_KAA_PORT);
      }
    
      // ...
    
      /**
      * Check credentials status for getting information
      * @return credential status
      */
      public void checkCredentialsStatus() {
      LOG.info("Enter endpoint ID:");
    
      // Reads endpoint ID (aka "endpoint key hash") from user input
      String endpointId = IOUtils.getUserInput().trim();
    
      LOG.info("Getting credentials status...");
      try {
      ApplicationDto app = getApplicationByName(APPLICATION_NAME);
      String appToken = app.getApplicationToken();
    
      // CredentialsStatus can be: AVAILABLE, IN_USE, REVOKED
      // if endpoint is not found on Kaa server, exception will be thrown
      CredentialsStatus status = adminClient.getCredentialsStatus(appToken, endpointId);
      LOG.info("Credentials for endpoint ID = {} are now in status: {}", endpointId, status.toString());
      } catch (Exception e) {
      LOG.error("Get credentials status for endpoint ID = {} failed. Error: {}", endpointId, e.getMessage());
      }
      }
    
      /**
      * Get application object by specified application name
      */
      private ApplicationDto getApplicationByName(String applicationName) {
      checkAuthorizationAndLogin();
    
      try {
      List<ApplicationDto> applications = adminClient.getApplications();
      for (ApplicationDto application : applications) {
      if (application.getName().trim().equals(applicationName)) {
      return application;
      }
      }
      } catch (Exception e) {
      LOG.error("Exception has occurred: " + e.getMessage());
      }
      return null;
      }
    
      /**
      * Checks authorization and log in
      */
      private void checkAuthorizationAndLogin() {
      if (!checkAuth()) {
      adminClient.login(tenantAdminUsername, tenantAdminPassword);
      }
      }
    
      /**
      * Do authorization check
      * @return true if user is authorized, false otherwise
      */
      private boolean checkAuth() {
      AuthResultDto.Result authResult = null;
      try {
      authResult = adminClient.checkAuth().getAuthResult();
      } catch (Exception e) {
      LOG.error("Exception has occurred: " + e.getMessage());
      }
      return authResult == AuthResultDto.Result.OK;
      }
    
      }
    

    您可以在 GitHub 上的 Kaa sample-apps projectCredentials Demo Application 中看到更多使用 AdminClient 的示例。

    了解解决方法

    1. Kaa NotificationsKaa Data Collection 功能结合使用。服务器向端点发送特定的单播通知(使用端点 ID),然后端点使用数据收集功能回复发送数据。服务器稍等片刻并检查端点的最后一个附加记录(通常在数据库中)的时间戳(按端点 ID)。所有消息都是异步发送的,因此您必须根据您的实际环境选择响应等待时间。
    2. 仅使用Kaa Data Collection 功能。这种方法更简单,但有一定的性能缺陷。如果您的端点必须根据其性质(测量传感器等)将数据发送到 Kaa 服务器,您可以使用它。端点只是定期向服务器发送数据。当服务器需要检查端点是否“在线”时,它会查询保存的数据日志(通常是数据库)以通过端点ID(key hash)获取最后一条记录并分析时间戳字段。

    * 要有效使用Kaa Data Collection 功能,您必须在选定的日志附加器(Kaa Admin UI)的设置中添加此类元数据:“端点密钥哈希”(与“端点 ID”相同)、“时间戳” .这会自动将所需字段添加到从端点接收到的每条日志记录中。

    【讨论】:

    • 非常感谢您重播安德烈,但这将触发现场端点内的事件,我们可以远程监控端点(KAA SDK)吗(办公室、门户网站、移动应用程序)或某种在线/离线端点。是否有任何功能或某种方式可以从 KAA Server 实现此要求。
    • 非常感谢安德烈。
    【解决方案2】:

    我自己是 Kaa 的新手,不确定是否有一种方法可以直接在 SDK 中确定这一点,但一种解决方法是您可以有一个额外的端点,您可以从该端点定期向所有其他端点发送事件并期待回复。当端点没有回复时,您就知道有问题了。

    【讨论】:

    • 但是,当我们有一百万台设备连接到 kaa 服务器时会怎样。您认为这种方法有效吗??
    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多