1. 创建maven工程
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.30.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
添加netty-all和junit,junit做单元测试用
2. 添加server主类
/**
* @author zhenlei
*/
public class MainServer {
private EventLoopGroup bossGroup = null;
private EventLoopGroup workerGroup = null;
private ServerBootstrap bootstrap = null;
private int port = 8080;
private int status = 0;
/**
* 设置,只执行一次
*
* @param optionalPort
*/
public void setup(Optional<Integer> optionalPort) {
if (status == 0) {
if (optionalPort.isPresent()) {
port = optionalPort.get();
}
Assert.assertNull("主进程不为空", bossGroup);
Assert.assertNull("工作进程不为空", workerGroup);
Assert.assertNull("启动器不为空", bootstrap);
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
bootstrap = new ServerBootstrap();
} else {
throw new RuntimeException("服务器已经启动");
}
}
/**
* 获取server状态
*
* @return
*/
public String getStatus() {
StringBuffer sb = new StringBuffer(6);
sb.append(bossGroup.isShutdown() ? "1" : "0");
sb.append(bossGroup.isShuttingDown() ? "1" : "0");
sb.append(bossGroup.isTerminated() ? "1" : "0");
sb.append(workerGroup.isShutdown() ? "1" : "0");
sb.append(workerGroup.isShuttingDown() ? "1" : "0");
sb.append(workerGroup.isTerminated() ? "1" : "0");
return sb.toString();
}
/**
* 启动server
*
* @param initializer 注入ChannelInitializer
* @return
* @throws Exception
*/
public ChannelFuture startup(ChannelInitializer<SocketChannel> initializer) throws Exception {
Assert.assertNotNull("主进程为空", bossGroup);
Assert.assertNotNull("工作进程为空", workerGroup);
Assert.assertNotNull("启动器为空", bootstrap);
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(initializer)
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture future = bootstrap.bind(port).sync();
System.out.println(String.format("server start http://127.0.0.1:%d", port));
return future;
}
/**
* 关闭server
*
* @throws Exception
*/
public void shutdown() throws Exception {
System.out.println(String.format("server shutdown http://127.0.0.1:%d", port));
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
// 确认停止server
if (workerGroup.isShuttingDown() || !workerGroup.isTerminated() || !workerGroup.isShutdown()) {
workerGroup.shutdownGracefully();
}
if (bossGroup.isShuttingDown() || !bossGroup.isTerminated() || !bossGroup.isShutdown()) {
bossGroup.shutdownGracefully();
}
}
}
3. 创建Handler和对应的ChannelInitialzer
EchoHandler,收到消息直接输出
/**
* @author zhenlei
*/
public class EchoHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ctx.writeAndFlush(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
EchoChannelInitialzer
/**
* @author zhenlei
*/
public class EchoChannelInitialzer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new EchoHandler());
}
}
4. 创建测试类
public class MainServerTest {
MainServer mainServer = null;
@Before
public void setup() {
mainServer = new MainServer();
mainServer.setup(Optional.empty());
}
@Test
public void testDiscard() throws Exception {
System.out.println("testDiscard");
mainServer.startup(new DiscardChannelInitialzer());
Thread.sleep(10000);
}
@Test
public void testEcho() throws Exception {
System.out.println("testEcho");
mainServer.startup(new EchoChannelInitialzer());
Thread.sleep(10000);
}
@Test
public void testHello() throws Exception {
System.out.println("testHello");
mainServer.startup(new HelloChannelInitialzer());
Thread.sleep(10000);
}
@After
public void cleanup() throws Exception {
mainServer.shutdown();
}
}
网友评论