CSE如何处理来自由远程AE创建的订阅的通知?

问题描述

假设我有一个IN-AE,IN-CSE和MN-CSE。 MN-CSE具有在IN-CSE中宣布的容器资源。 IN-AE通过公告资源中的链接,在MN-CSE中的容器上创建订阅,并且该订阅的NotificationURI是IN-AE的POA。

MN-CSE能够通过IN-CSE将通知路由回IN-AE的机制是什么?

例如,假设我在MN-CSE的pip install (package name)中有一个容器,并且我在IN-AE POST了以下对IN-CSE的订阅

import 'package:Flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:scroll/server.dart';

class FutureStream extends StatefulWidget {
  FutureStream({Key key}) : super(key: key);
  final String name = 'zaid salah';
  @override
  _FutureStreamState createState() => _FutureStreamState();
}

class _FutureStreamState extends State<FutureStream> {
  var uri = '${Server.domain}/web/vuecrud/public/test';
  var nexturl;
  ScrollController _scrollController = new ScrollController();
  List<Test> tempList = [];
  //determine if all data has been recieved
  var loadCompleted = false;

  Future<List<Test>> getData(uri) async {
    final response = await http.get(uri);
    if (response.statusCode == 200) {
      var testJson = json.decode(response.body);
      var data = testJson['data'];
      if (testJson['next_page_url'] != null) {
        nexturl = testJson['next_page_url'];
      } else {
        loadCompleted = true;
      }
      for (var item in data) {
        Test test =
            new Test(item["id"],item["name"],item["email"],item["password"]);
        tempList.add(test);
      }
      return tempList;
    } else {
      throw Exception('Failed to load Test');
    }
  }

  Future<List<Test>> data;
  @override
  void initState() {
    data = getData(uri);
    scrollindecator();
    super.initState();
  }

  void scrollindecator() {
    _scrollController.addListener(
      () {
        if (_scrollController.offset >=
                _scrollController.position.maxScrollExtent &&
            !_scrollController.position.outOfRange) {
          print('reach to bottom botton');
          if (!loadCompleted) {
            setState(() {
              //add more data to list
              data = getData(nexturl);
            });
          }
        }
      },);
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print("app called again");
    return Scaffold(
      appBar: AppBar(
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.search),onpressed: () {},),],centerTitle: true,title: Text("stream vs future"),body: SingleChildScrollView(
        controller: _scrollController,child: Column(
          mainAxisSize: MainAxisSize.min,children: <Widget>[
            FutureBuilder(
              future: data,builder: (BuildContext context,AsyncSnapshot snapshot) {
                if (!snapshot.hasData) {
                  return Container(
                    child: Center(
                      child: CircularProgressIndicator(),);
                } else {
                  //if (snapshot.connectionState == ConnectionState.done) {
                  return ListView.builder(
                      physics: ScrollPhysics(),shrinkWrap: true,itemCount: snapshot.data.length ?? 0,itemBuilder: (BuildContext contex,int index) {
                        if (index == snapshot.data.length - 1 &&
                            !loadCompleted) {
                          return Center(
                            child: new Opacity(
                              opacity: 1.0,child: new CircularProgressIndicator(),);
                        } else {
                          return ListTile(
                            leading: CircleAvatar(
                                backgroundColor: Colors.white,child:
                                    Text(snapshot.data[index].id.toString())),title: Text(snapshot.data[index].name),subtitle: Text(snapshot.data[index].email),trailing: Icon(
                              Icons.info,color: Colors.blue,onTap: () {
                              print(index);
                            },);
                        }
                      }
                      //  },);
                }
              },);
  }
}

class Test {
  final int id;
  final String name;
  final String email;
  final String password;
  Test(this.id,this.name,this.email,this.password);
}

注意:/mn-cse/ae1/container是IN-AE的POA,这是IN-CSE如何与IN-AE进行通话。

但是,假设MN-CSE不使用HTTP或无法路由到POST http://in-cse-host/mn-cse/ae1/container?rcn=2 HTTP/1.1 X-M2M-Origin: ae X-M2M-RI: ri1 { "sub": { "enc": { "net": [ 3 ] },"nu": [ "http://in-ae-host/notify" ],"nct": 1 } } 。 MN-CSE如何知道如何将带有该nu通知路由回正确的AE?

解决方法

CSE必须将其不是目标的任何请求转发到目标/目标CSE(传输请求)。请参阅TS-0001,表8.2.1.0-1“从注册人到注册人CSE,访问不同CSE中的资源”,以了解关于无跃点(目标CSE是相同的CSE),1跃点(直接注册商或直接)的详细说明CSE的registree CSE)和多跳(不是直接注册商或registree CSE)通信。

回答更新的问题

但是,假设MN-CSE不使用HTTP,或者无法路由到in-ae-host。 MN-CSE如何知道如何将带有该nu的通知路由回正确的AE?

这是怎么回事:MN-CSE开始在容器 / mn-cse / ae1 / container 下创建订阅。该过程的步骤之一涉及对 nu 中所有通知URI的验证请求。由于此操作失败(无论出于何种原因,MN-CSE都无法到达目标),验证请求失败,并且未创建订阅。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...