1. 程式人生 > 實用技巧 >Netty入門例項列子

Netty入門例項列子

maven專案Pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version> <!-- 我這裡用的1.5.9 -->
<relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>NettyText</groupId>
<artifactId>NettyText1</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-jmx</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--netty依賴-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version> 4.1.41.Final</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
</build>


</project>

Netty Server服務端


package com.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObject;

import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import java.net.InetSocketAddress;

public class NettyServer {

public static void main(String[] arg) throws InterruptedException
{
//定義兩個事件組
//接收連線但是不對連線做任何處理會把事情交給workerGroup去做
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {

//啟動服務
ServerBootstrap serverBootStrap = new ServerBootstrap();
serverBootStrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChildChannelHandler());
//繫結埠
ChannelFuture f = serverBootStrap.bind(8080).sync();
//等待服務端 監聽埠關閉
f.channel().closeFuture().sync();
}catch (Exception ex)
{

}
finally {
//優雅的關閉Netty
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}

//ChildChannelHandler加到了channel的pipeline裡面

private static class ChildChannelHandler extends ChannelInitializer<SocketChannel>
{

@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// LineBasedFrameDecoder 新增行解析器,新增stringDecoder
//StringDecoder作用就是將接收到的訊息轉為字串
socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
socketChannel.pipeline().addLast(new StringDecoder());

socketChannel.pipeline().addLast("TestHttpServerHandler",new TestHttpServerHandler());
}
}

}

TestHttpServerHandler(時間伺服器服務端)加到了channel的pipeline裡面

TestHttpServerHandler 繼承自ChannelInboundHandlerAdapter

package com.netty;

import com.fasterxml.jackson.core.io.CharTypes;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

import java.nio.ByteBuffer;
import java.util.Date;



public class TestHttpServerHandler extends ChannelInboundHandlerAdapter {

private final static String SEPARATOR = "\r\n";

private static int counter = 0;

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String body = (String) msg;
System.out.println(body + ", current counter is " + ++counter);

String currentTime = "QUERY TIME ORDER".equals(body) ?
new Date().toString() : "BAD ORDER";
ByteBuf buf = Unpooled.copiedBuffer((currentTime + SEPARATOR).getBytes());
ctx.write(buf);
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}

Netty Client客戶端

package com.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.string.StringDecoder;
public class NettyClient {



public static void main(String[] arg)
{
EventLoopGroup group = new NioEventLoopGroup();
try{

Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY,true)
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// LineBasedFrameDecoder 新增行解析器,新增stringDecoder
//StringDecoder作用就是將接收到的訊息轉為字串
pipeline.addLast(new LineBasedFrameDecoder(1024));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new LoggingHandler(LogLevel.INFO))
.addLast(new TimeClientHandler());

}
});

//start the client
ChannelFuture future = bootstrap.connect("127.0.0.1", 8080).sync();
//wait until the connection is closed
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//shut down the event loop to terminate all threads
group.shutdownGracefully();
}

}
}

客戶端的訊息處理器:

package com.netty;


import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TimeClientHandler extends ChannelInboundHandlerAdapter {
private static int counter = 0;

private byte[] req;

private final static String SEPARATOR = "\r\n";

public TimeClientHandler() {
req = ("QUERY TIME ORDER" + SEPARATOR).getBytes();
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf message = null;

for (int i = 0; i < 10; i++) {
message = Unpooled.buffer(req.length);
message.writeBytes(req);
ctx.writeAndFlush(message);
}


}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String body = (String) msg;
System.out.println("當前時間: " + body + ", current counter is " + ++counter);

}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.info("遇到錯誤");
ctx.close();
}
}

執行結果:

10:47:15.576 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] WRITE: 18B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 51 55 45 52 59 20 54 49 4d 45 20 4f 52 44 45 52 |QUERY TIME ORDER|
|00000010| 0d 0a |.. |
+--------+-------------------------------------------------+----------------+
10:47:15.577 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] FLUSH
10:47:15.591 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 1
10:47:15.591 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 2
10:47:15.591 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 3
10:47:15.592 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 4
10:47:15.592 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 5
10:47:15.592 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 6
10:47:15.592 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 7
10:47:15.593 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 8
10:47:15.593 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 9
10:47:15.594 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ: Tue Sep 08 10:47:15 CST 2020
當前時間: Tue Sep 08 10:47:15 CST 2020, current counter is 10
10:47:15.594 [nioEventLoopGroup-2-1] INFO io.netty.handler.logging.LoggingHandler - [id: 0xe5792ee2, L:/127.0.0.1:13998 - R:/127.0.0.1:8080] READ COMPLETE