Created
April 28, 2017 20:57
-
-
Save aaronzirbes/6641e29bf09f747c9c5d12b07637badd to your computer and use it in GitHub Desktop.
Basic Netty TCP server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.zirbes.sandbox | |
import groovy.util.logging.Slf4j | |
import io.netty.bootstrap.ServerBootstrap | |
import io.netty.channel.ChannelFuture | |
import io.netty.channel.ChannelHandlerContext | |
import io.netty.channel.ChannelInboundHandlerAdapter | |
import io.netty.channel.ChannelInitializer | |
import io.netty.channel.ChannelOption | |
import io.netty.channel.EventLoopGroup | |
import io.netty.channel.nio.NioEventLoopGroup | |
import io.netty.channel.socket.SocketChannel | |
import io.netty.channel.socket.nio.NioServerSocketChannel | |
@Slf4j | |
class MockTcpServer { | |
protected final int port | |
protected ChannelFuture channel | |
protected final EventLoopGroup masterGroup = new NioEventLoopGroup() | |
protected final EventLoopGroup workerGroup = new NioEventLoopGroup() | |
MockTcpServer(int port) { | |
this.port = port | |
} | |
void run() { | |
log.info "Starting MockTcpServer service on port=${port}" | |
Runtime.getRuntime().addShutdownHook(new Thread() { | |
@Override | |
void run() { shutdown() } | |
}) | |
try { | |
final ServerBootstrap bootstrap = new ServerBootstrap() | |
.group(masterGroup, workerGroup) | |
.channel(NioServerSocketChannel) | |
.childHandler(new ChannelInitializer<SocketChannel>() { | |
@Override | |
void initChannel(final SocketChannel ch) throws Exception { | |
ch.pipeline().addLast("request", | |
new ChannelInboundHandlerAdapter() { | |
@Override | |
void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { | |
String base64Bytes = msg.toString().bytes.encodeBase64() | |
log.info "Received request of type=${msg.class} bytes=${base64Bytes}" | |
final byte[] response = 'Hello.'.bytes | |
ctx.writeAndFlush(response) | |
} | |
@Override | |
void channelReadComplete(ChannelHandlerContext ctx) throws Exception { | |
ctx.flush() | |
} | |
@Override | |
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { | |
log.error 'Something went wrong.', cause | |
} | |
}) | |
} | |
}) | |
.option(ChannelOption.SO_BACKLOG, 128) | |
.childOption(ChannelOption.SO_KEEPALIVE, true) | |
log.info "Starting MockTcpServer service on port=${port}" | |
channel = bootstrap.bind(port).sync() | |
log.info "Shutting down MockTcpServer service on port=${port}" | |
} catch (final InterruptedException e) { | |
log.warn "Shutting down MockTcpServer service on port=${port} due to interruption" | |
} | |
} | |
void shutdown() { | |
workerGroup.shutdownGracefully() | |
masterGroup.shutdownGracefully() | |
try { | |
channel.channel().closeFuture().sync() | |
} catch (InterruptedException e) { | |
log.error "Shutting down MockTcpServer service on port=${port} due failed" | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment