@Test
  public void testLocalAddressReuse() throws Exception {

    for (int i = 0; i < 2; i++) {
      LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID);
      Bootstrap cb = new Bootstrap();
      ServerBootstrap sb = new ServerBootstrap();

      cb.eventLoop(new LocalEventLoop())
          .channel(new LocalChannel())
          .remoteAddress(addr)
          .handler(new TestHandler());

      sb.eventLoop(new LocalEventLoop(), new LocalEventLoop())
          .channel(new LocalServerChannel())
          .localAddress(addr)
          .childHandler(
              new ChannelInitializer<LocalChannel>() {
                @Override
                public void initChannel(LocalChannel ch) throws Exception {
                  ch.pipeline().addLast(new TestHandler());
                }
              });

      // Start server
      Channel sc = sb.bind().sync().channel();

      // Connect to the server
      Channel cc = cb.connect().sync().channel();

      // Send a message event up the pipeline.
      cc.pipeline().inboundMessageBuffer().add("Hello, World");
      cc.pipeline().fireInboundBufferUpdated();

      // Close the channel
      cc.close().sync();

      sb.shutdown();
      cb.shutdown();

      sc.closeFuture().sync();

      Assert.assertTrue(
          String.format(
              "Expected null, got channel '%s' for local address '%s'",
              LocalChannelRegistry.get(addr), addr),
          LocalChannelRegistry.get(addr) == null);
    }
  }
Example #2
0
  public void run() throws Exception {
    // Address to bind on / connect to.
    final LocalAddress addr = new LocalAddress(port);

    Bootstrap cb = new Bootstrap();
    ServerBootstrap sb = new ServerBootstrap();
    try {
      // Note that we can use any event loop to ensure certain local channels
      // are handled by the same event loop thread which drives a certain socket channel
      // to reduce the communication latency between socket channels and local channels.
      sb.eventLoop(new LocalEventLoop(), new LocalEventLoop())
          .channel(new LocalServerChannel())
          .localAddress(addr)
          .handler(
              new ChannelInitializer<LocalServerChannel>() {
                @Override
                public void initChannel(LocalServerChannel ch) throws Exception {
                  ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
                }
              })
          .childHandler(
              new ChannelInitializer<LocalChannel>() {
                @Override
                public void initChannel(LocalChannel ch) throws Exception {
                  ch.pipeline()
                      .addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoServerHandler());
                }
              });

      cb.eventLoop(new NioEventLoop())
          .channel(new LocalChannel())
          .remoteAddress(addr)
          .handler(
              new ChannelInitializer<LocalChannel>() {
                @Override
                public void initChannel(LocalChannel ch) throws Exception {
                  ch.pipeline()
                      .addLast(new LoggingHandler(LogLevel.INFO), new LocalEchoClientHandler());
                }
              });

      // Start the server.
      sb.bind().sync();

      // Start the client.
      Channel ch = cb.connect().sync().channel();

      // Read commands from the stdin.
      System.out.println("Enter text (quit to end)");
      ChannelFuture lastWriteFuture = null;
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      for (; ; ) {
        String line = in.readLine();
        if (line == null || "quit".equalsIgnoreCase(line)) {
          break;
        }

        // Sends the received line to the server.
        lastWriteFuture = ch.write(line);
      }

      // Wait until all messages are flushed before closing the channel.
      if (lastWriteFuture != null) {
        lastWriteFuture.awaitUninterruptibly();
      }
    } finally {
      sb.shutdown();
      cb.shutdown();
    }
  }