View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.examples.coap;
    21
    22  import java.io.UnsupportedEncodingException;
    23  import java.nio.ByteBuffer;
    24  import java.util.Map;
    25  import java.util.concurrent.ConcurrentHashMap;
    26
    27  import org.apache.mina.api.AbstractIoFutureListener;
    28  import org.apache.mina.api.AbstractIoHandler;
    29  import org.apache.mina.api.IdleStatus;
    30  import org.apache.mina.api.IoSession;
    31  import org.apache.mina.coap.CoapCode;
    32  import org.apache.mina.coap.CoapMessage;
    33  import org.apache.mina.coap.CoapOption;
    34  import org.apache.mina.coap.CoapOptionType;
    35  import org.apache.mina.coap.codec.CoapDecoder;
    36  import org.apache.mina.coap.codec.CoapEncoder;
    37  import org.apache.mina.coap.resource.AbstractResourceHandler;
    38  import org.apache.mina.coap.resource.CoapResponse;
    39  import org.apache.mina.coap.resource.ResourceRegistry;
    40  import org.apache.mina.filter.codec.ProtocolCodecFilter;
    41  import org.apache.mina.filter.query.RequestFilter;
    42  import org.apache.mina.transport.bio.BioUdpServer;
    43
    44  /**
    45   * A CoAP UDP server serving some resources.
    46   *
    47   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    48   */
    49  public class CoapServer {
    50
    51      public static void main(String[] args) {
    52
    53          final Map<String, IoSession> registration = new ConcurrentHashMap<>();
    54
    55          // create a CoAP resource registry
    56          final ResourceRegistry reg = new ResourceRegistry();
    57
    58          reg.register(new AbstractResourceHandler() {
    59
    60              @Override
    61              public String getPath() {
    62                  return "demo";
    63              }
    64
    65              @Override
    66              public CoapResponse handle(CoapMessage request, IoSession session) {
    67                  return new CoapResponse(CoapCode.CONTENT.getCode(), "niah niah niah niah niah\n niah niah niah\n"
    68                          .getBytes(), new CoapOption(CoapOptionType.CONTENT_FORMAT, new byte[] { 0 }));
    69              }
    70
    71              @Override
    72              public String getTittle() {
    73                  return "Some demo resource";
    74              }
    75
    76          });
    77
    78          reg.register(new AbstractResourceHandler() {
    79
    80              @Override
    81              public CoapResponse handle(CoapMessage request, IoSession session) {
    82                  String device = null;
    83                  try {
    84                      for (CoapOption o : request.getOptions()) {
    85                          if (o.getType() == CoapOptionType.URI_QUERY) {
    86                              String qr = new String(o.getData(), "UTF-8");
    87                              if (qr.startsWith("id=")) {
    88                                  device = qr.substring(2);
    89                              }
    90                          }
    91                      }
    92                      if (device != null) {
    93                          registration.put(device, session);
    94                          return new CoapResponse(CoapCode.CREATED.getCode(), null);
    95                      } else {
    96                          return new CoapResponse(CoapCode.BAD_REQUEST.getCode(), "no id=xxx parameter".getBytes("UTF-8"));
    97                      }
    98                  } catch (UnsupportedEncodingException e) {
    99                      throw new IllegalStateException("no UTF-8 in the JVM", e);
    100                 }
    101             }
    102
    103             @Override
    104             public String getPath() {
    105                 return "register";
    106             }
    107         });
    108
    109         BioUdpServer server = new BioUdpServer();
    110         final RequestFilter<CoapMessage, CoapMessage> rq = new RequestFilter<>();
    111
    112         server.setFilters(new ProtocolCodecFilter<CoapMessage, ByteBuffer, Void, Void>(
    113                 new CoapEncoder(), new CoapDecoder()), rq);
    114         // idle in 10 minute
    115         server.getSessionConfig().setIdleTimeInMillis(IdleStatus.READ_IDLE, 60 * 10_000);
    116         server.setIoHandler(new AbstractIoHandler() {
    117
    118             long start = System.currentTimeMillis();
    119             int count = 0;
    120
    121             @Override
    122             public void messageReceived(IoSession session, Object message) {
    123                 System.err.println("rcv : " + message);
    124
    125                 CoapMessage resp = reg.respond((CoapMessage) message, session);
    126                 System.err.println("resp : " + resp);
    127                 session.write(resp);
    128                 count++;
    129                 if (count >= 100_000) {
    130                     System.err.println("time for 100k msg : " + (System.currentTimeMillis() - start));
    131                     count = 0;
    132                     start = System.currentTimeMillis();
    133                 }
    134             }
    135
    136             @Override
    137             public void messageSent(IoSession session, Object message) {
    138                 System.err.println("sent : " + message);
    139             }
    140
    141             @Override
    142             public void sessionIdle(IoSession session, IdleStatus status) {
    143                 System.err.println("idle closing");
    144                 session.close(false);
    145             }
    146         });
    147
    148         try {
    149             server.bind(5683);
    150             new Thread() {
    151                 @Override
    152                 public void run() {
    153                     for (;;) {
    154                         for (IoSession s : registration.values()) {
    155                             rq.request(s, CoapMessage.get("st", true), 15_000).register(
    156                                     new AbstractIoFutureListener<CoapMessage>() {
    157                                         @Override
    158                                         public void completed(CoapMessage result) {
    159                                             System.err.println("status : " + result);
    160                                         }
    161                                     });
    162                         }
    163
    164                         try {
    165                             // let's poll every 10 seconds
    166                             Thread.sleep(10_000);
    167                         } catch (InterruptedException e) {
    168                             break;
    169                         }
    170                     }
    171                 }
    172             }.start();
    173
    174             for (;;) {
    175                 Thread.sleep(1_000);
    176             }
    177         } catch (InterruptedException e) {
    178             e.printStackTrace();
    179         }
    180     }
    181 }