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.core.service;
    21
    22  import junit.framework.Assert;
    23  import org.apache.mina.core.future.CloseFuture;
    24  import org.apache.mina.core.future.ConnectFuture;
    25  import org.apache.mina.core.future.IoFuture;
    26  import org.apache.mina.core.future.IoFutureListener;
    27  import org.apache.mina.core.session.IdleStatus;
    28  import org.apache.mina.core.session.IoSession;
    29  import org.apache.mina.filter.codec.ProtocolCodecFilter;
    30  import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
    31  import org.apache.mina.filter.logging.LoggingFilter;
    32  import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
    33  import org.apache.mina.transport.socket.nio.NioSocketConnector;
    34  import org.junit.Test;
    35  import org.slf4j.Logger;
    36  import org.slf4j.LoggerFactory;
    37
    38  import java.io.IOException;
    39  import java.net.InetSocketAddress;
    40  import java.nio.charset.Charset;
    41  import java.util.ArrayList;
    42  import java.util.List;
    43  import java.util.concurrent.CountDownLatch;
    44
    45  /**
    46   * test the AbstractIoService
    47   *
    48   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    49   */
    50  public class AbstractIoServiceTest {
    51
    52      private static final int PORT = 9123;
    53
    54      @Test
    55      public void testDispose() throws IOException, InterruptedException {
    56
    57          List threadsBefore = getThreadNames();
    58
    59          final IoAcceptor acceptor = new NioSocketAcceptor();
    60
    61          acceptor.getFilterChain().addLast("logger", new LoggingFilter());
    62          acceptor.getFilterChain().addLast("codec",
    63                  new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
    64
    65          acceptor.setHandler(new ServerHandler());
    66
    67          acceptor.getSessionConfig().setReadBufferSize(2048);
    68          acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
    69          acceptor.bind(new InetSocketAddress(PORT));
    70          System.out.println("Server running ...");
    71
    72          final NioSocketConnector connector = new NioSocketConnector();
    73
    74          // Set connect timeout.
    75          connector.setConnectTimeoutMillis(30 * 1000L);
    76
    77          connector.setHandler(new ClientHandler());
    78          connector.getFilterChain().addLast("logger", new LoggingFilter());
    79          connector.getFilterChain().addLast("codec",
    80                  new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
    81
    82          // Start communication.
    83          ConnectFuture cf = connector.connect(new InetSocketAddress("localhost", 9123));
    84          cf.awaitUninterruptibly();
    85
    86          IoSession session = cf.getSession();
    87
    88          // send a message
    89          session.write("Hello World!\r");
    90
    91          // wait until response is received
    92          CountDownLatch latch = (CountDownLatch) session.getAttribute("latch");
    93          latch.await();
    94
    95          // close the session
    96          CloseFuture closeFuture = session.close(false);
    97
    98          System.out.println("session.close called");
    99          //Thread.sleep(5);
    100
    101         // wait for session close and then dispose the connector
    102         closeFuture.addListener(new IoFutureListener<IoFuture>() {
    103
    104             public void operationComplete(IoFuture future) {
    105                 System.out.println("managed session count=" + connector.getManagedSessionCount());
    106                 System.out.println("Disposing connector ...");
    107                 connector.dispose(true);
    108                 System.out.println("Disposing connector ... *finished*");
    109
    110             }
    111         });
    112
    113         closeFuture.awaitUninterruptibly();
    114         acceptor.dispose(true);
    115
    116         List threadsAfter = getThreadNames();
    117
    118         System.out.println("threadsBefore = " + threadsBefore);
    119         System.out.println("threadsAfter  = " + threadsAfter);
    120
    121         // Assert.assertEquals(threadsBefore, threadsAfter);
    122
    123     }
    124
    125     public static class ClientHandler extends IoHandlerAdapter {
    126
    127         private static final Logger LOGGER = LoggerFactory.getLogger("CLIENT");
    128
    129         @Override
    130         public void sessionCreated(IoSession session) throws Exception {
    131             session.setAttribute("latch", new CountDownLatch(1));
    132         }
    133
    134         @Override
    135         public void messageReceived(IoSession session, Object message) throws Exception {
    136             LOGGER.info("client: messageReceived(" + session + ", " + message + ")");
    137             CountDownLatch latch = (CountDownLatch) session.getAttribute("latch");
    138             latch.countDown();
    139         }
    140
    141         @Override
    142         public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
    143             LOGGER.warn("exceptionCaught:", cause);
    144         }
    145     }
    146
    147     public static class ServerHandler extends IoHandlerAdapter {
    148
    149         private static final Logger LOGGER = LoggerFactory.getLogger("SERVER");
    150
    151         @Override
    152         public void messageReceived(IoSession session, Object message) throws Exception {
    153             LOGGER.info("server: messageReceived(" + session + ", " + message + ")");
    154             session.write(message.toString());
    155         }
    156
    157         @Override
    158         public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
    159             LOGGER.warn("exceptionCaught:", cause);
    160         }
    161
    162     }
    163
    164     public static void main(String[] args) throws IOException, InterruptedException {
    165         new AbstractIoServiceTest().testDispose();
    166     }
    167
    168     private List<String> getThreadNames() {
    169         List<String> list = new ArrayList<String>();
    170         int active = Thread.activeCount();
    171         Thread[] threads = new Thread[active];
    172         Thread.enumerate(threads);
    173         for (Thread thread : threads) {
    174             try {
    175                 String name = thread.getName();
    176                 list.add(name);
    177             } catch (NullPointerException ignore) {
    178             }
    179         }
    180         return list;
    181     }
    182
    183 }