Java使用Californium 实现CoAP协议交互代码案例

发布于:2025-04-01 ⋅ 阅读:(14) ⋅ 点赞:(0)

CoAP(Constrained Application Protocol)是一种专为资源受限设备设计的互联网协议,特别是在物联网(IoT)环境中。它旨在允许这些设备在低功耗、低带宽和不稳定的网络连接条件下进行通信。CoAP协议基于REST架构风格,类似于HTTP,但针对的是更小、更简单的设备。

以下是CoAP的一些关键特性:

  • 轻量级:CoAP被设计成非常小巧,以便可以在计算能力和内存都有限的设备上运行。
  • 基于REST:与HTTP类似,CoAP也使用请求/响应模型,并且支持GET、POST、PUT、DELETE等方法。
  • UDP基础:不同于HTTP使用TCP,CoAP是基于UDP的,这有助于减少延迟并提高效率,尤其是在不可靠的网络中。
  • 双层结构:CoAP包括消息层和请求/响应层。消息层处理UDP数据报的传输,而请求/响应层则负责实际的应用层交互。
  • 支持异步操作:即使是在不可靠的网络环境中,CoAP也能够通过非确认机制支持异步操作。
  • 安全机制:CoAP可以通过DTLS(Datagram Transport Layer Security)提供安全性,确保数据的保密性和完整性。

CoAP非常适合用于智能家居、智能城市以及其他需要大量小型传感器和执行器相互通讯的场景。由于其高效性和适应性,使得即使是资源极为有限的设备也能参与到更大的网络和服务生态系统中。

Java代码实现案例

使用 Eclipse Californium 库创建CoAP服务器和客户端,实现基本的GET、POST、观察模式。

引入maven依赖

github:https://github.com/eclipse-californium/californium

<dependency>
            <groupId>org.eclipse.californium</groupId>
            <artifactId>californium-core</artifactId>
            <version>3.13.0</version>
    </dependency>

GET请求示例

1、创建CoAP服务器

import org.eclipse.californium.core.CoapServer;
import org.eclipse.californium.core.server.resources.CoapResource;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.server.resources.CoapExchange;

public class CoAPServerExample {

    public static void main(String[] args) {
        // 创建一个CoAP服务器
        CoapServer server = new CoapServer();

        // 添加资源到服务器
        server.add(new HelloWorldResource());
        
        // 启动服务器
        server.start();
        System.out.println("CoAP Server started...");
    }

    // 定义一个资源类
    static class HelloWorldResource extends CoapResource {
        public HelloWorldResource() {
            // 资源名称为 "hello"
            super("hello"); 
            getAttributes().setTitle("Hello-World Resource");
        }

        @Override
        public void handleGET(CoapExchange exchange) {
            // 处理GET请求并返回响应
            exchange.respond("Hello, CoAP Client!");
        }
    }
}
  • 启动该程序后,服务器会监听默认端口 5683
  • 使用CoAP客户端访问资源路径 /hello,将收到响应 Hello, CoAP Client!

2、创建CoAP客户端

import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.MediaTypeRegistry;

public class CoAPClientExample {

    public static void main(String[] args) {
        // 创建一个CoAP客户端
        CoapClient client = new CoapClient("coap://localhost/hello");

        // 发送GET请求
        CoapResponse response = client.get();

        // 检查是否成功接收到响应
        if (response != null && response.isSuccess()) {
            System.out.println("Response from server: " + response.getResponseText());
        } else {
            System.out.println("Failed to get response from server.");
        }

        // 关闭客户端
        client.shutdown();
    }
}

客户端发送了GET请求到 /hello 资源路径,打印出服务器的响应:Response from server: Hello, CoAP Client

POST请求示例

在CoAP中,POST请求通常用于创建新资源或触发某些操作。

1、服务器端代码(支持POST请求)

static class DataResource extends CoapResource {
    public DataResource() {
        // 资源名称为 "data"
        super("data"); 
        getAttributes().setTitle("Data Resource");
    }

    @Override
    public void handlePOST(CoapExchange exchange) {
        // 获取客户端发送的数据
        String payload = exchange.getRequestText();
        System.out.println("Received data: " + payload);

        // 响应客户端
        exchange.respond("Data received: " + payload);
    }
}

添加到服务器:

server.add(new DataResource());

2、客户端代码(发送POST请求) 

public class CoAPPostClientExample {

    public static void main(String[] args) {
        // 创建一个CoAP客户端
        CoapClient client = new CoapClient("coap://localhost/data");

        // 设置POST请求的内容
        String payload = "This is a test message!";
        CoapResponse response = client.post(payload, MediaTypeRegistry.TEXT_PLAIN);

        // 检查响应
        if (response != null && response.isSuccess()) {
            System.out.println("Response from server: " + response.getResponseText());
        } else {
            System.out.println("Failed to get response from server.");
        }

        // 关闭客户端
        client.shutdown();
    }
}
  • 服务器会打印接收到的数据:Received data: This is a test message!
  • 客户端会打印服务器的响应:Response from server: Data received: This is a test message!

观察模式(Observe)

CoAP支持观察模式,允许客户端订阅资源的变化。以下是实现观察模式的简单示例。

1、服务器端代码(支持观察)

static class ObservableResource extends CoapResource {
    private int counter = 0;

    public ObservableResource() {
        super("observe");
        setObservable(true); // 设置资源可被观察
        getAttributes().setObservable(); // 标记为可观察
    }

    @Override
    public void handleGET(CoapExchange exchange) {
        // 返回当前计数器值
        exchange.respond("Counter: " + counter);

        // 模拟计数器变化
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(5000); // 每5秒更新一次
                    counter++;
                    changed(); // 通知观察者资源已更改
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

添加到服务器:

server.add(new ObservableResource());

2、客户端订阅观察 

import org.eclipse.californium.core.CoapHandler;
import org.eclipse.californium.core.CoapObserveRelation;

public class CoAPObserveClientExample {

    public static void main(String[] args) {
        // 创建一个CoAP客户端
        CoapClient client = new CoapClient("coap://localhost/observe");

        // 创建观察关系
        CoapObserveRelation relation = client.observe(new CoapHandler() {
            @Override
            public void onLoad(CoapResponse response) {
                // 当资源发生变化时,回调此方法
                System.out.println("Observation response: " + response.getResponseText());
            }

            @Override
            public void onError() {
                System.out.println("Error occurred during observation.");
            }
        });

        // sleep一段时间
        try {
            Thread.sleep(20000); 
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 取消观察
        relation.proactiveCancel();
        client.shutdown();
    }
}
  • 服务器每5秒更新计数器,并通知所有观察者。
  • 客户端会每隔5秒收到一次更新,打印类似以下内容:Observation response: Counter: x