学习 java netty (三) -- Channel

学习 java netty (三) – Channel

前言:netty封装的channel,看一下官网的定义

A nexus to a network socket or a component which is capable of I/O operations such as read, write, connect, and bind.

可以I/O操作(如读,写,连接和绑定)的连网套接字或组件

A channel provides a user:

All I/O operations are asynchronous

netty中channel所有的操作都是异步的,请求将立即返回,但不保证请求完成

Channels are hierarchical

channel是分层的,一个Channel可以有一个父母,取决于它是如何创建的,比如一个SocketChannel(客户端套接字)被ServerSocketChannel(服务端套接字)连接了,那么ServerSocketChannel就类似与SocketChannel的 parent

Downcast to access transport-specific operations

向下转型来访问特定的传输协议,也就是说转为子类型也可以访问父类型的操作

Release resources

释放资源,Channel内部也是Socket文件句柄,我们要close()


Channel是netty抽象出来的接口,不同与Nio中的channel,netty中的Channel封装了网络IO和网络IO相关的操作。功能非常多


源码:

//Channel是一个接口类,继承自AttributeMap和Comparable,AttributeMap是存储属性的一个map,Comparable接口强行对实现它的每个类的对象进行整体排序
public interface Channel extends AttributeMap, Comparable<Channel> {
    //返回唯一标识
    ChannelId id();
    //返回被注册的事件循环
    EventLoop eventLoop();
    //返回parent channel
    Channel parent();
    //返回channel(socket)的配置
    ChannelConfig config();
    //判断是否打开,注册,活跃
    boolean isOpen();
    boolean isRegistered();
    //源数据,可以获得底层的tcp参数设置等
    ChannelMetadata metadata();
    //本地地址和远端地址
    SocketAddress localAddress();
    SocketAddress remoteAddress();
    //关闭Channel,返回ChannelFuture意味着是异步的,不阻塞立即返回,在未来Future我们可以获得执行操作的状态
    ChannelFuture closeFuture();
    //数据是可读的
    boolean isWritable();
    long bytesBeforeWritable();
    Unsafe unsafe();
    ChannelPipeline pipeline();
    ByteBufAllocator alloc();
    ChannelPromise newPromise();
    ChannelProgressivePromise newProgressivePromise();
    ChannelFuture newSucceededFuture();
    ChannelFuture newFailedFuture(Throwable cause);
    ChannelPromise voidPromise();
    ChannelFuture bind(SocketAddress localAddress);
    ChannelFuture connect(SocketAddress remoteAddress);
    ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
    ChannelFuture disconnect();
    ChannelFuture close();
    ChannelFuture deregister();
    ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
    ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
    ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
    ChannelFuture disconnect(ChannelPromise promise);
    ChannelFuture close(ChannelPromise promise);
    ChannelFuture deregister(ChannelPromise promise);
    Channel read();
    ChannelFuture write(Object msg);
    ChannelFuture write(Object msg, ChannelPromise promise);
    Channel flush();
    ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
    ChannelFuture writeAndFlush(Object msg);
    interface Unsafe

从接口类可以看出Channel操作是非常多的,后面的方法我没有写注释,可以看见都是一些操作,返回ChannelFuture或者ChannelPromise,下面选一些重点来解释。


Channel

封装了许多协议tcp,udp等,通讯模型Nio,oio,Aio等,从上面可以看出对这些操作提供了一个整体的封装接口就是Channel,必要的时候可以进行转型。

接口中提供:

Channel的状态,isOpen(),isWritable()

Channel的配置参数,config()

Channel支持的操作,bind(),read(),connect()


ChannelFuture

所有的Channel操作都是异步的,Channel的返回ChannelFuture的一些操作并不阻塞,而是立即返回,在未来某个时刻我们能够获得状态来判断该操作的状态是完成还是进行还是取消。

注意ChannelFuture对象是操作一执行就立即返回了。ChannelFuture中提供的方法就是让检查操作完成状况。


ChannelPromise

继承关系:

Future <— ChannelFuture <— ChannelPromise

ChannelPromise继承了ChannelFuture,ChannelFuture方法主要是判断操作未来的状态,而ChannelPromise除了继承ChannelFuture的方法外,还实现了设置未来状态的写方法,

源码上写的是

Special {@link ChannelFuture} which is writable.

特殊的可写的ChannelFuture

比如ChannelFuture返回错误等情况,当我们使用ChannelPromise时,就能改变返回结果,唤醒其他操作,有点线程中条件变量的感觉。


ChannelPipeline

说到ChannelPipeline先要说责任链设计模式,简单来讲就是将一些能处理请求的对象串起来形成一条链,被处理的对象不知道被谁处理,所以在这条处理链上轮寻过,该被谁处理谁就接受此对象进行处理。

现实生活的例子,比如上级分派了一个任务做一款软件(被处理对象),放眼望去有一排攻城狮(处理请求对象),于是此任务在他们之间传递,每个攻城狮判断自己是否能做,能做就接受请求。

pipeline就是这条责任链,我们可以往上面注册,增添,删除处理事件对象,然后当待处理对象在此pipeline上传递时,哪个处理事件对象能处理则接收它。

责任链设计模式

部分代码:

public void initChannel(SocketChannel ch) throws Exception {
    ch.pipeline().addLast(new StringDecoder());
    //分隔符解码器
    DelimiterBasedFrameDecoder
    ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
    ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
}

上面添加了3个处理事件对象,字符串解码,分隔符解码,日志信息。当产生对应事件时,它们会接受并处理

注意:每个Channel在实例化的时候都会自动创建一个ChannelPipeline实例。ChannelPipeline是线程安全的,可以在任意时刻增加删除。


ChannelHandler

ChannelHandler就是ChannelPipeline上面注册的处理事件对象,每个ChannelHandler接口的实现类完成一定的功能,并可以灵活的在Pipeline流水线上增加,ChannelHandler也称为事件拦截器,遇到能处理的对象事件就拦截下来处理

ChannelHandler支持注解

@Sharable是多个Pipeline共用一个ChannelHandler

@skip是跳过此ChannelHandler


ChannelHandlerAdapter

ChannelHandlerAdapter给用户提供了ChannelHandler的适配器,我们可以自定义类来继承ChannelHandlerAdapter然后根据自己需要如何处理事件对象来重新实现ChannelHandler的方法。

例子:

public class ServerHandler extends ChannelHandlerAdapter {
    ServerHandler(){
        System.out.println("ServerHandler被创建");
    }
    //重写此方法
    public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception{
        ctx.write(msg);
        System.out.println("发送msg");
        ByteBuf buf = (ByteBuf)msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("server收到:" + body);
        ctx.write(resp);
 }

    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception{
        //将write数据先写到缓冲区中,等到complete状态再刷新缓冲区
        ctx.flush();
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
        //有错误时打印错误并且关闭ctx
        logger.log(Level.WARNING, "unexcepted exception from downstream", cause);
        ctx.close();
    }
}

到此Channel和Channel关系密切的类和接口差不多就简单介绍完了,我们大致能知道它们的原理和它们的用法后,在看和使用其他继承它们的拓展类就方便多了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-15 01:32:44

学习 java netty (三) -- Channel的相关文章

学习 java netty (二) -- ServerBootstrap

前言:我们自己使用java nio开发网络程序是非常繁琐的,netty为我们做好了一切,其中ServerBootstrap是一个启动辅助类,了解它我们就能开发出简单的nio 服务端程序. 不理解Nio中channel和handler等可参考上一篇文章 学习 java netty (一) – java nio ServerBootstrap(): //创建一个ServerBootstrap对象 ServerBootstrap server = new ServerBootstrap; Server

学习 java netty (一) -- java nio

前言:最近在研究java netty这个网络框架,第一篇先介绍java的nio. java nio在jdk1.4引入,其实也算比较早的了,主要引入非阻塞io和io多路复用.内部基于reactor模式. nio核心: - buffer - channel - selector buffer: 类似网络编程中的缓冲区,有 ByteBuffer 字节 CharBuffer 字符 IntBuffer DoubleBuffer- 常用的有ByteBuffer和CharBuffer java nio buf

系统学习 Java IO (三)----FileInputStream/FileOutputStream &amp; RandomAccessFile

目录:系统学习 Java IO---- 目录,概览 FileInputStream 这是一个简单的FileInputStream示例: InputStream input = new FileInputStream("D:\\input.txt"); int data = input.read(); while(data != -1) { //do something with data... doSomethingWithData(data); data = input.read()

学习Java第三周

这是学习java的第三周 上周想要学习的这周也完成了,研究和测试代码花费了大约2个小时,发现这些内容方法居多,想要熟练掌握就要好好记忆了 包装类 数字处理类 Object类 Java类包 内部类 下一周准备复习一下这两周学的,加深印象,所以学习内容待定. 包装类 数字处理类 内部类 成员内部类 局部内部类 静态内部类 原文地址:https://www.cnblogs.com/ywqtro/p/11220757.html

学习java 第三天

运算符分类编辑 运算符指明对操作数的运算方式.组成表达式的Java操作符有很多种.运算符按照其要求的操作数数目来分,可以有单目运算符.双目运算符和三目运算符,它们分别对应于1个.2个.3个操作数.运算符按其功能来分,有算术运算符.赋值运算符.关系运算符.逻辑运算符.位运算符和其他运算符.[1] 算术 单目:+(取正)-(取负) ++(自增1) - -(自减1) 双目:+ - * / %(取余) 三目:a>b?true:false 说明:当a大于b的时候,为true(也就是冒号之前的值),否则为f

使用eclipse学习java第三课

第一节: GUI:感觉自己写得不好,直接给连接吧,今天坳上头比较大,这个链接对于如满还是写的很不错的:http://www.cnblogs.com/vamei/archive/2013/04/17/3000908.html 采集 #HUABAN_WIDGETS .HUABAN-red-normal-icon-button, .HUABAN-red-large-icon-button, .HUABAN-red-small-icon-button, .HUABAN-white-normal-icon

学习java第三天---面向对象

方法 定义方法: 修饰符 返回类型 方法名(参数列表){ 语句: return 方法返回值: } 修饰符:public private this变量:隐含变量this,指向当前实例 方法参数: 方法可以包含0个或任意个参数.方法参数用于接收传递给方法的变量值.调用方法时,必须严格按照参数的定义一一传递 可变参数: 可变参数用类型...定义,可变参数相当于数组类型: 参数绑定: 调用方把参数传递给实例方法时,调用时传递的值会按参数位置一一绑定. 构成方法 构造方法的名称是类名.构造方法的参数没有限

java学习笔记(三)java中的修饰符abstract、static与final

一.四种访问级别的访问范围 访问级别 访问修饰符 同类 同包 子类 不同的包 公开 public 受保护 protected 默认 没有访问修饰符 私有的 private 二.使用abstract修饰符需要遵守的语法规则 1.抽象类中可以没有抽象方法,但是包含抽象方法的类必须定义为抽象类,即用abstract修饰: 2.抽象类跟抽象方法不能被final修饰符修饰: 3.抽象类中可以有非抽象方法,因为继承抽象类的子类必须重写父类中所有的抽象方法,因此抽象类中不能有抽象构造方法和抽象静态方法: 4.

201671010117 2016-2017-2 《Java程序设计》Java第三周学习心得

Java第三周学习心得 通过这一周的学习,了解到了Java的核心部分,理解了用户自定义类的定义 ,了解了对象的声明 ,了解了使用构造函数初始化对象 ,使用类属性与方法的使用,了解了package和import语句的用途,知道了假设你面对现实世界的一个对象,你不会把它的属性和处理方法分开,程序设计也是一样.面向对象程序设计(OOP):一种新的思维方法,更接近人类处理现实世界问题的自然表示方法.面向对象的语言有:C++,Smalltalk,Java等.面向对象程序设计的几个主要概念:抽象数据类型.类