分布式项目(三)CoAp client and server

上回说到Web manage的构建,完成的对产品,物模型中的属于数据,设备数据,并把对应的数据缓存到redis中,接下来就开始coap客户端和服务器的构建。

coap

现阶段PC网络交互中较多的是使用tcp和http协议,但物联网设备都要求较小的功耗、较小的带宽,并且CPU、内存都是有限的,所以在这种需求下,http相对就不实用了,因为http相对臃肿,而CoAP是受限制的应用协议的代名词,CoAp和http一样都是应用层的协议,并且它是一种类http协议,相同的如请求响应模式,url方式,请求方法(做了缩减),响应码(做了简化),不同的是CoAp是基于UDP的,可以双向通信(既是客户端又是服务端),并且CoAp协议非常的小,最小的数据包仅为4k。

coap报文

  • Var:版本编号

  • T:报文类型,coap定义了4种报文类型

    1. CON:需要确认的消息,可实现可靠性传输
    2. NON:不要确认的消息,消息传输不可靠
    3. ACK:确认应到消息,与CON对象
    4. RST:复位,要求消息重传
  • TKL:标识符长度,CoAp定义了两种标识符,Message Id(必须)和Token(非必须)

  • Code:响应码,如4.04,5.00,和http中的404、500功能类似

  • Message Id:报文编号

  • Token:标识符具体的内容

  • Option:可选选项参数,一个或多个,可设置Uri-Host、Uri-Port、Uri-Path和Uri-Query,CoAp对Option定了3部分

    1. Delta:当前Option的编号,等于前面所有Option delta的总和
    2. Length:表示value部分具体的长度
    3. value:当前Option承载的具体内容
  • 1111 1111B:报文与所承载的数据分隔符

  • Payload:所承载的数据实体

请求方法

请求方法和http类似,coap定义了4种请求方式

  • get:获取资源
  • post:创建资源
  • put:更新资源
  • delete:删除资源

coap数据格式

和http类似,用户定义所承载的数据的具体格式,如text/html,application/json

上面就是对coap做了一个简单的介绍,对coap协议有个大概的了解,接下来就开始对client和server的编码了,当然笔者这里也不可能自己写一个对coap的实现,笔者这里使用的是californium-core。

californium-core client

构建iot-coap-client模块,加入californium-core依赖

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

这里我们用定时任务来模拟物理网设备数据的定时发送

创建Scheduler类,因我们定了byte和json两种数据格式,所以这里编写sendByte()和sendJson(),iot-pt设定一类物理设备只能发送一种数据格式,但这里为了方便,笔者就使用具体发送数据格式的方法来模拟一种具体的设备,使用随机数来模拟设备的数据变化。

private Random ra = new Random();
    @Scheduled(fixedRate = 2000)
    public void sendByte() throws URISyntaxException {
        //创建请求资源
        URI uri = new URI("coap://localhost:5683/iot-byte?201904151718");
        CoapClient client = new CoapClient(uri);

        StringBuilder sb = new StringBuilder();
        sb.append(ra.nextInt(999)%(999-100+1)+100);
        sb.append(new BigDecimal(ra.nextDouble()).setScale(2,
		BigDecimal.ROUND_HALF_UP));
        //请求资源
        CoapResponse response = client.post(sb.toString(),
		MediaTypeRegistry.TEXT_PLAIN);
        if(response !=null){
            System.out.println(response.getCode());  //请求状态码
            System.out.println(response.getOptions());  //选项参数
            System.out.println(response.getResponseText());  //内容文本信息
            System.out.println(Utils.prettyPrint(response));  //报文内容
        }
    }
@Scheduled(fixedRate = 4000)
    public void sendJson() throws URISyntaxException {
	//创建请求资源,201904151718 设备唯一编码,模拟imie
        URI uri =  new URI("coap://localhost:5683/iot-json?2019041717"); 
        CoapClient client = new CoapClient(uri);
        //温度
        int temperature = ra.nextInt(999)%(999-100+1)+100;
        //湿度
        String humidity = String.valueOf(new BigDecimal(ra.nextDouble())
		.setScale(2, 
		BigDecimal.ROUND_HALF_UP));
        Map map = new HashMap<String,String>();
        map.put("T",String.valueOf(temperature));
        map.put("H",humidity);
        String json = JSONObject.toJSONString(map);
        client.post(json,MediaTypeRegistry.APPLICATION_JSON);
    }

Copa发送数据的客户端已经写好了,就下了开始server的撸码

californium-core Server

首先还是构建iot-coap-server模块,加入californium-core依赖

  1. 创建服务器启动,ServerStart类
[@Component](https://my.oschina.net/u/3907912)
public class ServerStart {
    @Value("${coap.port}")
    private int port;
    @Autowired
    private IotByteHandler iotHandler;
    @Autowired
    private IotJsonHandler iotJsonHandler;
    public void start(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                CoapServer server = new CoapServer(port);
                server.add(iotHandler);
                server.add(iotJsonHandler);
                server.start();
            }
        });
        thread.start();
    }
}

因为我这里使用的是spring boot 的核心组件,spring boot启动完成后由于没有应用线程运行,所以项目jvm会自动退出,因为这里使用Thread线程来启动CoapServer,CoapServer会一直监听消息接受,jvm守护进程就不会退出。

接下来编写IotByteHandler和IotJsonHandler,这种Handler的实现方式和netty有点类似。

@Component
public class IotByteHandler extends CoapResource {

    public IotByteHandler(@Value("${coap.iot.byte}") String name) {
        super(name);
    }

    @Override
    public void handlePOST(CoapExchange exchange) {
        //状态码
        System.out.println("code---"+exchange.getRequestCode());
        //选项参数
        System.out.println("Options---"+exchange.getRequestOptions());
        //文本内容
        System.out.println("text"+exchange.getRequestText());

        System.out.println(exchange.getRequestOptions());

    }
}
@Component
public class IotJsonHandler extends CoapResource {
    public IotJsonHandler(@Value("${coap.iot.json}") String name) {
        super(name);
    }

    @Override
    public void handlePOST(CoapExchange exchange) {
        System.out.println("option---"+exchange.getRequestOptions());
        System.out.println("json---" + exchange.getRequestText());
    }
}

spring boot runner 启动coapServer

@Component
public class CoapApplicationRunner implements ApplicationRunner {
    @Autowired
    private ServerStart serverStart;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        serverStart.start();
    }
}

接着启动CoapServer和CoapClient,看数据是否符合我们预定的格式发送过来了

ok,数据以及发到服务器了,安装我们的架构设备,CoApServer需要把数据整理并发送到kafka的,因此kafka很多地方都需要使用,所以在这里独立构建一个kafka模块,iot-kafka。

KafkaSource负责把协议服务收到的消息发送给kafak

@Component
public class KafkaSource {

    @Autowired
    private KafkaTemplate kafkaTemplate;

    public void send(KafkaSourceVO vo){
        kafkaTemplate.send(SOURCE_TOPIC,JSONObject.toJSONString(vo));
    }
}

修改CoApServer的IotByteHandler和IotJsonHandler,加入kafka写消息

@Component
public class IotByteHandler extends CoapResource {

    @Autowired
    private KafkaSource kafkaSource;

    public IotByteHandler(@Value("${coap.iot.byte}") String name) {
        super(name);
    }

    @Override
    public void handlePOST(CoapExchange exchange) {
        //状态码
        System.out.println("code---"+exchange.getRequestCode());
        //选项参数
        System.out.println("Options---"+exchange.getRequestOptions());
        //文本内容
        System.out.println("text"+exchange.getRequestText());

        System.out.println(exchange.getRequestOptions());

        KafkaSourceVO vo = new KafkaSourceVO(exchange.getRequestOptions().
		getUriQuery().get(0),exchange.getRequestText(),new Date());
        kafkaSource.send(vo);
        exchange.respond(CoAP.ResponseCode.CONTENT,"ok");
    }
}
@Component
public class IotJsonHandler extends CoapResource {
    @Autowired
    private KafkaSource kafkaSource;

    public IotJsonHandler(@Value("${coap.iot.json}") String name) {
        super(name);
    }

    @Override
    public void handlePOST(CoapExchange exchange) {
        KafkaSourceVO vo = new KafkaSourceVO(exchange.getRequestOptions().
		getUriQuery().get(0),exchange.g
etRequestText(),new Date());
        kafkaSource.send(vo);
        exchange.respond(CoAP.ResponseCode.CONTENT,"ok");
    }
}
public class KafkaSourceVO {
    //设备唯一码
    private String imei;
    //数据
    private String data;
    //这里用服务接送到消息的时间模拟设备采集数据的时间
    private Date collTime;

再次启动CoApServer和CoApClient,验证是否把数据写如kafka了。

结束语

接下来就是Mapping Server的实现了,请听下回分解,具体的代码细节在git

https://gitee.com/distant/iot-pt.git

转载于:https://my.oschina.net/u/2258281/blog/3039687

CoAP (Constrained Application Protocol) 是一种面向物联网的应用层协议,它是专门为受限设备和网络设计的轻量级协议。Spring Boot 是一个快速开发 Web 应用程序的框架,它提供了很多开箱即用的功能。在 Spring Boot 中整合 CoAP 可以让我们更方便地开发物联网应用程序。 下面是整合 CoAP 的步骤: 1. 添加依赖 在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>org.eclipse.californium</groupId> <artifactId>californium-core</artifactId> <version>2.0.0-M3</version> </dependency> <dependency> <groupId>org.eclipse.californium</groupId> <artifactId>californium-proxy</artifactId> <version>2.0.0-M3</version> </dependency> ``` 这些依赖将帮助我们使用 CoAP 协议。 2. 创建 CoapServer 创建一个 CoapServer 类,并添加 @Configuration 和 @EnableCoapServer 注解,示例如下: ``` @Configuration @EnableCoapServer public class CoapServerConfig { @Bean public CoapServer coapServer() { return new CoapServer(); } } ``` 3. 创建资源 创建一个 CoapResource 类,并添加 @Component 注解,示例如下: ``` @Component public class MyResource extends CoapResource { public MyResource() { super("myResource"); } @Override public void handleGET(CoapExchange exchange) { exchange.respond("Hello, CoAP!"); } } ``` 这个资源将会响应 GET 请求,并返回 "Hello, CoAP!"。 4. 注册资源 在 CoapServer 类中,将资源注册到服务器上,示例如下: ``` @Configuration @EnableCoapServer public class CoapServerConfig { @Bean public CoapServer coapServer() { CoapServer server = new CoapServer(); server.add(new MyResource()); return server; } } ``` 5. 运行服务器 创建一个 main 方法,并运行服务器,示例如下: ``` @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } } ``` 现在,你可以使用 CoAP 协议通过访问 "coap://localhost:5683/myResource" 来访问资源了。 以上就是整合 CoAP 的步骤。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值