【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();
            }
        });
    }

}
相关推荐
工程师老罗9 小时前
Image(图像)的用法
java·前端·javascript
早點睡3909 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-swiper
javascript·react native·react.js
globaldomain9 小时前
什么是用于长距离高速传输的TCP窗口扩展?
开发语言·网络·php
沈阳信息学奥赛培训9 小时前
#undef 指令 (C/C++)
c语言·开发语言·c++
2401_873204659 小时前
分布式系统安全通信
开发语言·c++·算法
jump_jump9 小时前
深入 JavaScript Iterator Helpers:从 API 到引擎实现
javascript·性能优化
swipe10 小时前
把 JavaScript 原型讲透:从 `[[Prototype]]`、`prototype` 到 `constructor` 的完整心智模型
前端·javascript·面试
Dxy123931021610 小时前
JS发送请求的方法详解
开发语言·javascript·ecmascript
sw12138910 小时前
C++中的代理模式实战
开发语言·c++·算法
難釋懷10 小时前
Lua语法入门-条件控制、函数
开发语言·junit·lua