ネッティーはJBOSSによって提供されるJavaのオープンソースのフレームワークです。ネッティーは非同期、イベント駆動型のネットワークアプリケーションフレームワークと急速に高性能、高信頼性のネットワーク・サーバとクライアントプログラムを開発するためのツールを提供します。言い換えれば、ネッティーは、あなたが顧客に契約のいくつかの種類、サーバ・アプリケーションを実現するために、例えば、ネットワークアプリケーションを開発するために迅速かつ簡単ネッティーを使用できることを保証するために、NIOのクライアントベース、サーバー側のプログラミングフレームワークです。TCPとUDPに基づいてソケットサービスの開発:ネッティーは、以下のようなネットワークアプリケーションの開発をプログラミングのプロセスを簡素化し、合理化に対応しています。「高速」と「簡単」は、メンテナンスやパフォーマンスの問題を発生させるために使用されていません。ネッティーは、実装経験(FTP、SMTP、HTTP、およびその他のバイナリテキストプロトコルを含む)複数のプロトコルを吸収し、プロジェクトの後に非常によく設計されています。最後に、ネッティーは成功し、開発の容易性を確保するための方法を発見しただけでなく、アプリケーションの性能、安定性と拡張性を確保するために、
この記事では、単純なケースSpringBootネッティーとクライアントサービスを使用する方法について説明し、関連するパラメータを説明しました
、ネッティーサーバー
1、輸入に依存
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.36.Final</version>
</dependency>
2、ネッティーサーバプロセッサを書きます
/**
* @author Gjing
*
* netty服务端处理器
**/
@Slf4j
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
/**
* 客户端连接会触发
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("Channel active......");
}
/**
* 客户端发消息会触发
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info("服务器收到消息: {}", msg.toString());
ctx.write("你也好哦");
ctx.flush();
}
/**
* 发生异常触发
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
3、ネッティーサーバの初期化子を書きます
/**
* @author Gjing
*
* netty服务初始化器
**/
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//添加编解码
socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
socketChannel.pipeline().addLast(new NettyServerHandler());
}
}
4、ネッティーサービスの開始を書きます
/**
* @author Gjing
* <p>
* 服务启动监听器
**/
@Component
@Slf4j
public class NettyServer {
public void start(InetSocketAddress socketAddress) {
//new 一个主线程组
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
//new 一个工作线程组
EventLoopGroup workGroup = new NioEventLoopGroup(200);
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ServerChannelInitializer())
.localAddress(socketAddress)
//设置队列大小
.option(ChannelOption.SO_BACKLOG, 1024)
// 两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
.childOption(ChannelOption.SO_KEEPALIVE, true);
//绑定端口,开始接收进来的连接
try {
ChannelFuture future = bootstrap.bind(socketAddress).sync();
log.info("服务器启动开始监听端口: {}", socketAddress.getPort());
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//关闭主线程组
bossGroup.shutdownGracefully();
//关闭工作线程组
workGroup.shutdownGracefully();
}
}
}
5、クラスを開始
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
//启动服务端
NettyServer nettyServer = new NettyServer();
nettyServer.start(new InetSocketAddress("127.0.0.1", 8090));
}
}
6、結果開始
二、ネッティークライアント
図1に示すように、依存関係を追加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.36.Final</version>
</dependency>
2、クライアントプロセッサを書きます
/**
* @author Gjing
*
* 客户端处理器
**/
@Slf4j
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("客户端Active .....");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info("客户端收到消息: {}", msg.toString());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
3、クライアントの初期化子を書きます
/**
* @author Gjing
* 客户端初始化器
**/
public class NettyClientInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("decoder", new StringDecoder());
socketChannel.pipeline().addLast("encoder", new StringEncoder());
socketChannel.pipeline().addLast(new NettyClientHandler());
}
}
4、クライアントを書きます
/**
* @author Gjing
**/
@Component
@Slf4j
public class NettyClient {
public void start() {
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap()
.group(group)
//该参数的作用就是禁止使用Nagle算法,使用于小数据即时传输
.option(ChannelOption.TCP_NODELAY, true)
.channel(NioSocketChannel.class)
.handler(new NettyClientInitializer());
try {
ChannelFuture future = bootstrap.connect("127.0.0.1", 8090).sync();
log.info("客户端成功....");
//发送消息
future.channel().writeAndFlush("你好啊");
// 等待连接被关闭
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
group.shutdownGracefully();
}
}
}
5、クラスを開始
@SpringBootApplication
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
//启动netty客户端
NettyClient nettyClient = new NettyClient();
nettyClient.start();
}
}
6、結果開始
- クライアント
- サーバー
詳細な3、ChannelOption引数
1、ChannelOption.SO_BACKLOG
同時になるようChannelOption.SO_BACKLOGは、関数内でバックログパラメータを聞き、関数が聞く(int型socketfd、int型バックログ)が接続キューサーバーを初期化するために使用することができ、サーバは順次処理のクライアント接続処理を要求し、TCP / IPプロトコルに対応しますサーバーが処理されるのを待っているキュー内のクライアントの接続要求を処理できない場合に、複数のクライアントに接続されたクライアントを扱うことができ、backlogパラメータは、キューのサイズを指定します
2、ChannelOption.SO_REUSEADDR
ChanneOption.SO_REUSEADDR对应于套接字选项中的SO_REUSEADDR,这个参数表示允许重复使用本地地址和端口,比如,某个服务器进程占用了TCP的80端口进行监听,此时再次监听该端口就会返回错误,使用该参数就可以解决问题,该参数允许共用该端口,这个在服务器程序中比较常使用,比如某个进程非正常退出,该程序占用的端口可能要被占用一段时间才能允许其他进程使用,而且程序死掉以后,内核一需要一定的时间才能够释放此端口,不设置SO_REUSEADDR就无法正常使用该端口。
3、ChannelOption.SO_KEEPALIVE
Channeloption.SO_KEEPALIVE参数对应于套接字选项中的SO_KEEPALIVE,该参数用于设置TCP连接,当设置该选项以后,连接会测试链接的状态,这个选项用于可能长时间没有数据交流的连接。当设置该选项以后,如果在两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
4、ChannelOption.SO_SNDBUF和ChannelOption.SO_RCVBUF
ChannelOption.SO_SNDBUF参数对应于套接字选项中的SO_SNDBUF,ChannelOption.SO_RCVBUF参数对应于套接字选项中的SO_RCVBUF这两个参数用于操作接收缓冲区和发送缓冲区的大小,接收缓冲区用于保存网络协议站内收到的数据,直到应用程序读取成功,发送缓冲区用于保存发送数据,直到发送成功。
5、ChannelOption.SO_LINGER
ChannelOption.SO_LINGER参数对应于套接字选项中的SO_LINGER,Linux内核默认的处理方式是当用户调用close()方法的时候,函数返回,在可能的情况下,尽量发送数据,不一定保证会发生剩余的数据,造成了数据的不确定性,使用SO_LINGER可以阻塞close()的调用时间,直到数据完全发送
6、ChannelOption.TCP_NODELAY
ChannelOption.TCP_NODELAYパラメータはNagleアルゴリズムに関連するパラメータを使用して、TCP_NODELAYソケットオプションに相当し、Nagleアルゴリズムは、そうではなく、再度入力を送信するよりも、より大きな小パケットフレームに組み立て、次に送信されます効果的な方法は、ネットワークの負荷を改善するためものの、他のデータは、送信された大規模なデータパケットに集合するための十分なデータパケットは、お待ちしておりますが、それは、このパラメータの役割はNagleアルゴリズムの使用を禁止している間、使用して、遅延の原因となったときリアルタイムで小さなデータ伝送は、TCP_NODELAYに対応しTCP_CORKで、このオプションは、1回のファイル転送のためのデータを送信する際に送信されるデータの最大量まで待つことです。
7、IP_TOS
優先度およびQoSオプションを記述するために使用されるIPパケットのIPヘッダのタイプオブサービスフィールドに設定されたIPパラメータ。
8、ALLOW_HALF_CLOSURE
ネッティーパラメータは、ローカル接続の閉鎖端の先端が閉じられている、デフォルトはFalseです。値がFalseである場合、接続は自動的に閉じられ、真の場合、userEventTriggered ChannelInboundHandlerトリガ()メソッド、イベントChannelInputShutdownEvent。
。第四に、網状のfuture.channel()closeFuture()syncは();最後に使用することは何ですか?
メインスレッドがサブスレッドの終了を実行するためにここで待ってます、子スレッドは、本当にに耳を傾け、要求を受け入れ、closeFuture()で、チャンネルリスナーを開くことであるリスナーが閉じられたチャネルにあれば、チャネルが閉じているかどうかを監視する責任があり、子メインスレッドは、子スレッドの同期の結果を待つように、スレッドは、syncUninterruptibly()解放されます
この記事では、より深い使用が必要であれば、あなたはこのデモアドレスのソースコードを学ぶために公式サイトに行くことができる、シンプルな基本的な使用について説明します:SpringBoot-ネッティー