【netty】Channel

channel 的主要作用

• close() 可以用来关闭 channel

• closeFuture() 用来处理 channel 的关闭

sync 方法作用是同步等待 channel 关闭

而 addListener 方法是异步等待 channel 关闭

• pipeline() 方法添加处理器

• write() 方法将数据写入

• writeAndFlush() 方法将数据写入并刷出

ChannelFuture.sync()

阻塞住当前线程,知道建立链接的nio线程建立链接之后,才会继续往下进行。

ChannelFuture.connect的方法是异步非阻塞的方法,所以在连接的服务器的时候,会单独的用零一个nio线程去做connect操作(或许预计1s的时间),但是此时mian线程会继续往下执行代码。向服务器发送数据信息。

java 复制代码
        Bootstrap bootstrap = new Bootstrap();
        ChannelFuture channelFuture = bootstrap.group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringEncoder());
                    }
                })
                .connect(new InetSocketAddress("localhost", 8081));
        channelFuture.sync();
        Channel channel = channelFuture.channel();
        channel.writeAndFlush("hello").channel();
        
        System.out.println(channel);

如果没有调用sync方法,则server会接受不到client的消息。从打印channel的信息状态来看,我们也是之后channel的信息,没有链接服务器的信息,这里做个对比。

bash 复制代码
Connected to the target VM, address: '127.0.0.1:53547', transport: 'socket'
[id: 0x31ab0c71]
bash 复制代码
Connected to the target VM, address: '127.0.0.1:54059', transport: 'socket'
[id: 0x151e03d2, L:/127.0.0.1:54062 - R:localhost/127.0.0.1:8081]

ChannelFuture.addListener回调对象

异步处理结果

在nio线程建立链接之后,会调用operationComplete方法

sync是等建立链接的nio线程来建立之后,主线程发送并等待结果

addListener是开启了一个新的线程,发送并等待结果

java 复制代码
  Bootstrap bootstrap = new Bootstrap();
        ChannelFuture channelFuture = bootstrap.group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringEncoder());
                    }
                })
                .connect(new InetSocketAddress("localhost", 8081));


        channelFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                Channel channel = channelFuture.channel();
                log.info("{}", channel);
                channel.writeAndFlush("heloo");
            }
        });
    }

ClosedFuture

复制代码
channel.close();也是异步操作,单独开启一个线程去进行关闭操作

这就导致了,我们紧随其后的在close之后进行一些善后处理工作,可能会在真正close的线程之前就开始操作了。

如果我们想在close之后去进行一些操作,例如善后处理的动作,那么就需要closedFuture

同步操作sync

java 复制代码
@Slf4j
public class TestChannelFutureClient {

    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        ChannelFuture channelFuture = bootstrap.group(nioEventLoopGroup)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringEncoder());
                    }
                })
                .connect(new InetSocketAddress("localhost", 8081));


        Channel channel = channelFuture.sync().channel();

        new Thread(() -> {
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String s = scanner.nextLine();
                if ("q".equals(s)) {
                    channel.close();
                    break;
                }
                channel.writeAndFlush(s);
            }
              }).start();

        ChannelFuture closeFuture = channel.closeFuture();

        closeFuture.sync();
        log.info("在channel关闭之后,才执行");
    }

}

异步操作addListener

java 复制代码
package org.example.netty_study.channelFuture;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.Scanner;

@Slf4j
public class TestChannelFutureClient {

    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        ChannelFuture channelFuture = bootstrap.group(nioEventLoopGroup)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringEncoder());
                    }
                })
                .connect(new InetSocketAddress("localhost", 8081));


        Channel channel = channelFuture.sync().channel();

        new Thread(() -> {
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String s = scanner.nextLine();
                if ("q".equals(s)) {
                    channel.close();
                    break;
                }
                channel.writeAndFlush(s);
            }
              }).start();

        ChannelFuture closeFuture = channel.closeFuture();


        closeFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                log.info("在channel关闭之后,才执行");
                nioEventLoopGroup.shutdownGracefully();
            }
        });
    }

}
相关推荐
云深处@2 小时前
【C++11】包装器,智能指针
开发语言·c++
量子炒饭大师2 小时前
【C++入门】Cyber深度漫游者的初始链路——【类与对象】初始化成员列表
开发语言·c++·dubbo·类与对象·初始化成员列表
独自破碎E2 小时前
BISHI43 讨厌鬼进货
android·java·开发语言
纯.Pure_Jin(g)2 小时前
【Python练习四】Python 算法与进阶特性实战:数组、序列化与位运算专项练习(3道经典练习带你巩固基础——看完包会)
开发语言·vscode·python
阿猿收手吧!2 小时前
【C++】模块:告别头文件新时代
开发语言·c++
简单Janeee2 小时前
[Vue 3 从零到上线]-第三篇:网页的指挥官——指令系统 (v-if, v-for, v-bind, v-on)
前端·javascript·vue.js
星火开发设计2 小时前
虚析构函数:解决子类对象的内存泄漏
java·开发语言·前端·c++·学习·算法·知识
t198751282 小时前
MATLAB水声信道建模:方法、实现与应用
开发语言·matlab
maplewen.2 小时前
C++ 多态原理深入理解
开发语言·c++·面试