diff --git a/example/src/main/java/io/netty/example/uptime/UptimeClient.java b/example/src/main/java/io/netty/example/uptime/UptimeClient.java index 81ff7c767f..6f7d9a2dd9 100644 --- a/example/src/main/java/io/netty/example/uptime/UptimeClient.java +++ b/example/src/main/java/io/netty/example/uptime/UptimeClient.java @@ -38,34 +38,27 @@ public final class UptimeClient { // Sleep 5 seconds before a reconnection attempt. static final int RECONNECT_DELAY = Integer.parseInt(System.getProperty("reconnectDelay", "5")); // Reconnect when the server sends nothing for 10 seconds. - static final int READ_TIMEOUT = Integer.parseInt(System.getProperty("readTimeout", "10")); + private static final int READ_TIMEOUT = Integer.parseInt(System.getProperty("readTimeout", "10")); private static final UptimeClientHandler handler = new UptimeClientHandler(); + private static final Bootstrap bs = new Bootstrap(); public static void main(String[] args) throws Exception { - configureBootstrap(new Bootstrap()).connect(); + EventLoopGroup group = new NioEventLoopGroup(); + bs.group(group) + .channel(NioSocketChannel.class) + .remoteAddress(HOST, PORT) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new IdleStateHandler(READ_TIMEOUT, 0, 0), handler); + } + }); + bs.connect(); } - private static Bootstrap configureBootstrap(Bootstrap b) { - return configureBootstrap(b, new NioEventLoopGroup()); - } - - static Bootstrap configureBootstrap(Bootstrap b, EventLoopGroup g) { - b.group(g) - .channel(NioSocketChannel.class) - .remoteAddress(HOST, PORT) - .handler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - ch.pipeline().addLast(new IdleStateHandler(READ_TIMEOUT, 0, 0), handler); - } - }); - - return b; - } - - static void connect(Bootstrap b) { - b.connect().addListener(new ChannelFutureListener() { + static void connect() { + bs.connect().addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.cause() != null) { diff --git a/example/src/main/java/io/netty/example/uptime/UptimeClientHandler.java b/example/src/main/java/io/netty/example/uptime/UptimeClientHandler.java index 493465d90f..3ad89bd7ce 100644 --- a/example/src/main/java/io/netty/example/uptime/UptimeClientHandler.java +++ b/example/src/main/java/io/netty/example/uptime/UptimeClientHandler.java @@ -15,10 +15,8 @@ */ package io.netty.example.uptime; -import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.EventLoop; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; @@ -70,12 +68,11 @@ public class UptimeClientHandler extends SimpleChannelInboundHandler { public void channelUnregistered(final ChannelHandlerContext ctx) throws Exception { println("Sleeping for: " + UptimeClient.RECONNECT_DELAY + 's'); - final EventLoop loop = ctx.channel().eventLoop(); - loop.schedule(new Runnable() { + ctx.channel().eventLoop().schedule(new Runnable() { @Override public void run() { println("Reconnecting to: " + UptimeClient.HOST + ':' + UptimeClient.PORT); - UptimeClient.connect(UptimeClient.configureBootstrap(new Bootstrap(), loop)); + UptimeClient.connect(); } }, UptimeClient.RECONNECT_DELAY, TimeUnit.SECONDS); } diff --git a/example/src/main/java/io/netty/example/uptime/UptimeServer.java b/example/src/main/java/io/netty/example/uptime/UptimeServer.java new file mode 100644 index 0000000000..e50b589590 --- /dev/null +++ b/example/src/main/java/io/netty/example/uptime/UptimeServer.java @@ -0,0 +1,67 @@ +/* + * Copyright 2017 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.example.uptime; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; + +/** + * Uptime server is served as a connection server. + * So it simply discards all message received. + */ +public final class UptimeServer { + private static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); + private static final UptimeServerHandler handler = new UptimeServerHandler(); + + private UptimeServer() { + } + + public static void main(String[] args) throws Exception { + + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) { + ch.pipeline().addLast(handler); + } + }); + + // Bind and start to accept incoming connections. + ChannelFuture f = b.bind(PORT).sync(); + + // Wait until the server socket is closed. + // In this example, this does not happen, but you can do that to gracefully + // shut down your server. + f.channel().closeFuture().sync(); + } finally { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + } +} diff --git a/example/src/main/java/io/netty/example/uptime/UptimeServerHandler.java b/example/src/main/java/io/netty/example/uptime/UptimeServerHandler.java new file mode 100644 index 0000000000..3fe1374312 --- /dev/null +++ b/example/src/main/java/io/netty/example/uptime/UptimeServerHandler.java @@ -0,0 +1,35 @@ +/* + * Copyright 2017 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.example.uptime; + +import io.netty.channel.ChannelHandler.Sharable; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +@Sharable +public class UptimeServerHandler extends SimpleChannelInboundHandler { + @Override + public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { + // discard + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + // Close the connection when an exception is raised. + cause.printStackTrace(); + ctx.close(); + } +} diff --git a/run-example.sh b/run-example.sh index 1c064ac125..b29078ac4a 100755 --- a/run-example.sh +++ b/run-example.sh @@ -38,6 +38,7 @@ EXAMPLE_MAP=( 'memcache-binary-client:io.netty.example.memcache.binary.MemcacheClient' 'stomp-client:io.netty.example.stomp.StompClient' 'uptime-client:io.netty.example.uptime.UptimeClient' + 'uptime-server:io.netty.example.uptime.UptimeServer' 'sctpecho-client:io.netty.example.sctp.SctpEchoClient' 'sctpecho-server:io.netty.example.sctp.SctpEchoServer' 'localecho:io.netty.example.localecho.LocalEcho'