Distributed project (3) CoAp client and server

Last time, I talked about the construction of Web manage. After the completion of the product, the belonging data in the object model, the device data, and the corresponding data is cached in redis, and then the construction of the coap client and server is started.

coap

At this stage, tcp and http protocols are mostly used in PC network interaction, but IoT devices all require less power consumption, less bandwidth, and limited CPU and memory. Therefore, under this requirement, http Relatively impractical, because http is relatively bloated, and CoAP is synonymous with restricted application protocols. CoAp, like http, is an application layer protocol, and it is an http-like protocol, the same as request response mode, url method , request method (reduced), response code (simplified), the difference is that CoAp is based on UDP, can communicate in both directions (both client and server), and the CoAp protocol is very small, the smallest packet 4k only.

coap message

  • Var: version number

  • T: packet type, coap defines 4 packet types

    1. CON: A message that needs to be acknowledged for reliable transmission
    2. NON: Do not acknowledge messages, message delivery is not reliable
    3. ACK: Acknowledgment should arrive message, with CON object
    4. RST: reset, request message retransmission
  • TKL: identifier length, CoAp defines two identifiers, Message Id (required) and Token (not required)

  • Code: Response code, such as 4.04, 5.00, similar to 404 and 500 in http

  • Message Id: message number

  • Token: The specific content of the identifier

  • Option: Optional option parameter, one or more, you can set Uri-Host, Uri-Port, Uri-Path and Uri-Query, CoAp defines 3 parts for Option

    1. Delta: the number of the current Option, equal to the sum of all previous Option deltas
    2. Length: Indicates the specific length of the value part
    3. value: the specific content carried by the current Option
  • 1111 1111B: Packet and carried data separator

  • Payload: the data entity carried

request method

The request method is similar to http, coap defines 4 request methods

  • get: get the resource
  • post: create a resource
  • put: update resource
  • delete: delete the resource

coap data format

Similar to http, the user defines the specific format of the data carried, such as text/html, application/json

The above is a brief introduction to coap. I have a general understanding of the coap protocol. Next, I will start coding the client and server. Of course, it is impossible for the author to write an implementation of coap here. The author uses it here. is californium-core.

californium-core client

Build the iot-coap-client module and add the californium-core dependency

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

Here we use timed tasks to simulate the timed transmission of physical network device data

Create the Scheduler class, because we have set two data formats, byte and json, so here we write sendByte() and sendJson(). Just use the method of sending the data format to simulate a specific device, and use the random number to simulate the data change of the device.

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);
    }

The client for Copa to send data has been written, so let's start the server code

californium-core Server

First, build the iot-coap-server module and add the californium-core dependency

  1. Create server startup, ServerStart class
[@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();
    }
}

Because I am using the core components of spring boot here, since there is no application thread running after spring boot is completed, the project jvm will automatically exit, because the Thread thread is used to start the CoapServer, the CoapServer will always listen for message acceptance, and the jvm daemon will will not quit.

Next, write IotByteHandler and IotJsonHandler. The implementation of this Handler is somewhat similar to 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 starts coapServer

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

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

Then start CoapServer and CoapClient to see if the data is sent in our predetermined format

ok, the data has been sent to the server, install our architecture equipment, CoApServer needs to organize and send the data to kafka, so kafka needs to be used in many places, so build a kafka module here independently, iot-kafka.

KafkaSource is responsible for sending messages received by the protocol service to kafak

@Component
public class KafkaSource {

    @Autowired
    private KafkaTemplate kafkaTemplate;

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

Modify CoApServer's IotByteHandler and IotJsonHandler, and add kafka to write messages

@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;

Start CoApServer and CoApClient again to verify whether the data is written as kafka.

concluding remarks

Next is the implementation of Mapping Server, please listen to the next decomposition, the specific code details are in git

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

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324154731&siteId=291194637