【问题标题】:Eclipse Californium CoAP wildcard as url pathEclipse Californium CoAP 通配符作为 url 路径
【发布时间】:2016-05-18 22:00:36
【问题描述】:

我正在使用 Eclipse Californium 开发 CoAP 应用程序,该应用程序将仅显式声明根资源路径,其余资源应通过通配符 /root/* 提供和解析,就像在 REST API 或 servlet 上一样。

有什么方法可以实现吗?

【问题讨论】:

    标签: java eclipse url iot californium


    【解决方案1】:

    好的,我设法做到了。

    因此,在对他们的源代码进行了几个小时的挖掘之后,这就是最终要做的事情。

    请注意,它可以工作,但它只是为了展示它是如何完成的,它仍然是一个正在进行的工作(我在 3 小时内完成了这个),因为我删除了一些代码,如观察者等。

    一旦我有时间,我会更多地研究 Californium Api 并使其通用和优化,我将创建一个 Github 项目并将其链接到此处。

    1 : 创建模型类

    public class ProxyRes {
    
        public  CoapResource coapRes;
        public  String  path;
    
        public ProxyRes () {
        }
    
        public CoapResource getCoapRes () {
            return coapRes;
        }
    
        public void setCoapRes (CoapResource coapRes) {
            this.coapRes = coapRes;
        }
    
        public String getPath () {
            return path;
        }
    
        public void setPath (String path) {
            this.path = path;
        }
    }
    

    2 : 创建一个应该注入通配符列表的抽象 CoapResource

    public abstract class AbstractResource extends CoapResource {
    
        private LinkedList<String> wildcards;
    
        protected AbstractResource (String name) {
            super (name);
        }
    
        protected AbstractResource (String name, boolean visible) {
            super (name, visible);
        }
    
        public LinkedList<String> getWildcards () {
            return wildcards;
        }
    
        public void setWildcards (LinkedList<String> wildcards) {
            this.wildcards = wildcards;
        }
    }
    

    3 : 创建一个扩展 AbstractResource 的温度资源

    public class TemperatureResource extends AbstractResource {
    
        public TemperatureResource () {
            super (ResourceSpecs.House.Sensors.Temperature);
    
            getAttributes ().setTitle ("Temperature resource !");
        }
    
        @Override
        public void handleGET (CoapExchange exchange) {
            String response = "The temperature";
            if (getWildcard () != null) {
                response += " of the " + getWildcard ().get (0) + " on the " + getWildcard ().get (1);
            }
            response += " is : 25 degree C";
    
            exchange.respond (response);
        }
    }
    

    4 : 在我的 eclipse 项目的根目录下创建一个资源目录,其中包含我的资源的 json conf 文件

    {
        "verb": "get",
        "endpoint": "/houses/*/rooms/*/sensors/temperature",
    
        "class": "com.wild.coap.resources.TemperatureResource"
    }
    

    5:创建资源加载器(将加载资源的规范定义并独立实例化它们而不是在服务器上创建树的类)

    public class ResourcesLoader {
    
        private final static String Path = new File (".").getAbsolutePath () + File.separator + "resources";
    
        private List<ProxyRes>  resourcesList;
    
        public ResourcesLoader () throws Exception {
            resourcesList   = new ArrayList<ProxyRes> ();
    
            File resources  = new File (Path);
            for (String resName : resources.list ()) {
                File resFile    = new File (resources, resName);
                InputStream is  = new FileInputStream (resFile);
                JsonObject o    = new JsonObject (is);
    
                resourcesArr.add (o);
                resourcesList.add (buildObject (o));
            }
        }
    
        private ProxyRes buildObject (JsonObject o) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            ProxyRes r = new ProxyRes ();
            r.setPath (o.getString ("endpoint"));
    
            Class<?> clazz  = Class.forName (o.getString ("class"));
            CoapResource coapRes = (CoapResource)clazz.newInstance ();
            r.setCoapRes (coapRes);
    
            return r;
        }
    
        public List<ProxyRes> getResourcesList () {
            return resourcesList;
        }
    }
    

    6 : 创建自定义 MessageDeliverer

    public class DynamicMessageDeliverer implements MessageDeliverer {
    
        private final List<ProxyRes>    resources;
    
        public DynamicMessageDeliverer (List<ProxyRes> resources) {
            this.resources  = resources;
        }
    
        public void deliverRequest (final Exchange exchange) {
            Request request         = exchange.getRequest ();
            List<String> path       = request.getOptions ().getUriPath ();
    
            final Resource resource = registerResources (path);     
            if (resource != null) {
                executeResource (exchange, resource);           
            } else {
                exchange.sendResponse (new Response (ResponseCode.NOT_FOUND));
                throw new RuntimeException ("Did not find resource " + path.toString() + " requested by " + request.getSource()+":"+request.getSourcePort());
            }
        }
    
        private void executeResource (final Exchange exchange, final Resource resource) {
            // Get the executor and let it process the request
            Executor executor = resource.getExecutor ();
            if (executor != null) {
                exchange.setCustomExecutor ();
                executor.execute (new Runnable () {
    
                    public void run () {
                        resource.handleRequest (exchange);
                    } 
                });
            } else {
                resource.handleRequest (exchange);
            }
        }
    
        private Resource registerResources (List<String> list) {
            LinkedList<String> path         = new LinkedList<String> (list);
            String flatRequestedEndpoint    = Arrays.toString (path.toArray ());
            LinkedList<String> wildcards    = new LinkedList <String> ();
            ProxyRes retainedResource       = null;
    
            for (ProxyRes proxyRes : resources) {
                String[] res = proxyRes.getPath ().replaceFirst ("/", "").split ("/");
    
                int length = res.length;
                if (length != path.size ()) {
                    continue;
                }
    
                String flatResEndpoint = Arrays.toString (res);
                if (flatResEndpoint.equals (flatRequestedEndpoint)) {
                    retainedResource = proxyRes;
                    break;
                }
    
                boolean match = true;
    
                for (int i = 0; i < length; i ++) {
                    String str = res[i];
                    if (str.equals ("*")) {
                        wildcards.add (path.get (i));
                        continue;
                    }
    
                    if (!str.equals (path.get (i))) {
                        match = false;
                        break;
                    }
                }
    
                if (!match) {
                    wildcards.clear ();
                    continue;
                }
    
                retainedResource = proxyRes;
                break;
            }
    
            if (retainedResource == null) {
                return null;
            }
    
            ((AbstractResource)retainedResource.getCoapRes ()).setWildcard (wildcards);
            return retainedResource.getCoapRes ();
        }
    
        public void deliverResponse (Exchange exchange, Response response) {
            if (response == null) throw new NullPointerException();
            if (exchange == null) throw new NullPointerException();
            if (exchange.getRequest() == null) throw new NullPointerException();
            exchange.getRequest().setResponse(response);
            Request request         = exchange.getRequest ();
            List<String> path       = request.getOptions ().getUriPath ();
            System.out.println ("Path retrieved : " + Arrays.toString (path.toArray ()));
        }
    }
    

    7 : 创建服务器

    public class WildCoapServer extends CoapServer {
    
        private static final int COAP_PORT = NetworkConfig.getStandard  ().getInt  (NetworkConfig.Keys.COAP_PORT);
    
        public WildCoapServer () throws Exception {
    
            // add endpoints on all IP addresses
            addEndpoints ();
    
            ResourcesLoader resLoader   = new ResourcesLoader ();
            List<ProxyRes> resources    = resLoader.getResourcesList ();
    
            setMessageDeliverer (new DynamicMessageDeliverer (resources));
        }
    
        @Override
        protected Resource createRoot () {
            return new WildRootResource ();
        }
    
        // Add individual endpoints listening on default CoAP port on all IPv4 addresses of all network interfaces.
        private void addEndpoints () {
            for (InetAddress addr : EndpointManager.getEndpointManager ().getNetworkInterfaces ()) {
                // only binds to IPv4 addresses and localhost
                if (addr instanceof Inet4Address || addr.isLoopbackAddress ()) {
                    InetSocketAddress bindToAddress = new InetSocketAddress (addr, COAP_PORT);
                    addEndpoint (new CoapEndpoint (bindToAddress));
                }
            }
        }
    }
    

    8 : 启动服务器

    public class Main {
    
        public static void main (String[] args) {
    
            try {
                WildCoapServer server = new WildCoapServer ();
                server.start ();
            } catch  (Exception e) {
                throw new RuntimeException (e.getMessage (), e);
            }
        }
    }
    

    9 : 使用客户端的温度资源

    public class Client {
    
        public static void main  (String[] args) {
    
            URI uri = null;
            try {
                uri = new URI ("coap://192.168.200.1:5683/houses/house1/rooms/kitchen/sensors/temperature");
            } catch  (URISyntaxException e) {
                throw new RuntimeException (e.getMessage (), e);
            }
    
            CoapClient client       = new CoapClient (uri);
    
            CoapResponse response   = client.get ();
    
            if (response != null) {
    
                System.out.println (response.getCode ());
                System.out.println (response.getOptions ());
                System.out.println (response.getResponseText ());
    
                System.out.println ("\nADVANCED\n");
                // access advanced API with access to more details through .advanced ()
                System.out.println (Utils.prettyPrint (response));
    
            } else {
                System.out.println ("No response received.");
            }       
        }
    }
    

    希望对某人有所帮助。

    【讨论】:

    • 我正在寻找相同的解决方案。您是否设法获得了一个 github 存储库?可以分享一下吗?
    【解决方案2】:

    这是我解决这个问题的方法。

    CoapResource wildcard = new CoapResource("*") {
    
        @Override
        public void handleGET(CoapExchange exchange) {
            ...
        }
    };
    
    CoapResource root = new CoapResource("root") {
        @Override
        public Resource getChild(String name) {
            return wildcard;
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-25
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-17
      相关资源
      最近更新 更多