`
秋天的童话穷
  • 浏览: 79326 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Netty入门5

    博客分类:
  • Java
阅读更多

1.9. 关闭你的应用


如果你运行了TimeClient,你肯定可以注意到,这个应用并没有自动退出而只是在那里保持着无意义的运行。跟踪堆栈记录你可以发现, 这里有一些运行状态的I/O线程。为了关闭这些I/O线程并让应用优雅的退出,你需要释放这些由ChannelFactory分配的资源。

一个典型的网络应用的关闭过程由以下三步组成:

关闭负责接收所有请求的server socket

关闭所有客户端socket或服务端为响应某个请求而创建的socket

释放ChannelFactory使用的所有资源。

 

为了让TimeClient执行这三步,你需要在TimeClient.main()方法内关闭唯一的客户连接以及ChannelFactory使用的所有资源,这样做便可以优雅的关闭这个应用。

package org.jboss.netty.example.time;  
 
public class TimeClient {  
    public static void main(String[] args) throws Exception {  
        ...  
        ChannelFactory factory = ...;  
        ClientBootstrap bootstrap = ...;  
        ...  
        ChannelFuture future  = bootstrap.connect(...);  
        future.awaitUninterruptible();  
        if (!future.isSuccess()) {  
            future.getCause().printStackTrace();  
        }  
        future.getChannel().getCloseFuture().awaitUninterruptibly();  
        factory.releaseExternalResources();  
    }  
} 

 代码说明

 

1) ClientBootstrap对象的connect方法返回一个ChannelFuture对象,这个ChannelFuture对象将告知这个连接操 作的成功或失败状态。同时这个ChannelFuture对象也保存了一个代表这个连接操作的Channel对象引用。

 

2) 阻塞式的等待,直到ChannelFuture对象返回这个连接操作的成功或失败状态。

 

3) 如果连接失败,我们将打印连接失败的原因。如果连接操作没有成功或者被取消,ChannelFuture对象的getCause()方法将返回连接失败的原因。

 

4) 现在,连接操作结束,我们需要等待并且一直到这个Channel通道返回的closeFuture关闭这个连接。每一个Channel都可获得自己的closeFuture对象,因此我们可以收到通知并在这个关闭时间点执行某种操作。

 

并且即使这个连接操作失败,这个closeFuture仍旧会收到通知,因为这个代表连接的 Channel对象将会在连接操作失败后自动关闭。

 

5) 在这个时间点,所有的连接已被关闭。剩下的唯一工作是释放ChannelFactory通道工厂使用的资源。这一步仅需要调用 releaseExternalResources()方法即可。包括NIO Secector和线程池在内的所有资源将被自动的关闭和终止。

 

 

 

关闭一个客户端应用是很简单的,但又该如何关闭一个服务端应用呢?你需要释放其绑定的端口并关闭所有接受和打开的连接。为了做到这一点,你需要使用一种数据结构记录所有的活动连接,但这却并不是一件容易的事。幸运的是,这里有一种解决方案,ChannelGroup

 

ChannelGroupJava 集合 API的一个特有扩展,ChannelGroup内部持有所有打开状态的Channel通道。如果一个Channel通道对象被加入到 ChannelGroup,如果这个Channel通道被关闭,ChannelGroup将自动移除这个关闭的Channel通道对象。此外,你还可以对 一个ChannelGroup对象内部的所有Channel通道对象执行相同的操作。例如,当你关闭服务端应用时你可以关闭一个ChannelGroup 内部的所有Channel通道对象。

 

为了记录所有打开的socket,你需要修改你的TimeServerHandler实现,将一个打开的Channel通道加入全局的ChannelGroup对象,TimeServer.allChannels:

@Override 
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {  
    TimeServer.allChannels.add(e.getChannel());  
} 

 代码说明

 

是的,ChannelGroup是线程安全的。

 

 

现在,所有活动的Channel通道将被自动的维护,关闭一个服务端应用有如关闭一个客户端应用一样简单。

package org.jboss.netty.example.time;  
 
public class TimeServer {  
 
    static final ChannelGroup allChannels = new DefaultChannelGroup("time-server" );  
 
    public static void main(String[] args) throws Exception {  
        ...  
        ChannelFactory factory = ...;  
        ServerBootstrap bootstrap = ...;  
        ...  
        Channel channel  = bootstrap.bind(...);  
        allChannels.add(channel);  
        waitForShutdownCommand();  
        ChannelGroupFuture future = allChannels.close();  
        future.awaitUninterruptibly();  
        factory.releaseExternalResources();  
    }  
} 

 代码说明

1) DefaultChannelGroup需要一个组名作为其构造器参数。这个组名仅是区分每个ChannelGroup的一个标示。

2) ServerBootstrap对象的bind方法返回了一个绑定了本地地址的服务端Channel通道对象。调用这个Channel通道的close()方法将释放这个Channel通道绑定的本地地址。

3) 不管这个Channel对象属于服务端,客户端,还是为响应某一个请求创建,任何一种类型的Channel对象都会被加入ChannelGroup。因此,你尽可在关闭服务时关闭所有的Channel对象。

4) waitForShutdownCommand()是一个想象中等待关闭信号的方法。你可以在这里等待某个客户端的关闭信号或者JVM的关闭回调命令。

5) 你可以对ChannelGroup管理的所有Channel对象执行相同的操作。在这个例子里,我们将关闭所有的通道,这意味着绑定在服务端特定地址的 Channel通道将解除绑定,所有已建立的连接也将异步关闭。为了获得成功关闭所有连接的通知,close()方法将返回一个 ChannelGroupFuture对象,这是一个类似ChannelFuture的对象。

 

1.10. 总述


在这一章节,我们快速浏览并示范了如何使用Netty开发网络应用。下一章节将涉及更多的问题。同时请记住,为了帮助你以及能够让Netty基于你的回馈得到持续的改进和提高,Netty社区 将永远欢迎你的问题及建议。

分享到:
评论

相关推荐

    Netty入门教程文档

    Netty入门教程文档 Netty是Java的网络编程框架,广泛应用于数据采集服务中,本文将对Netty的基本概念和应用进行详细介绍,并将其与ETL技术结合,讲解如何使用Netty进行数据流转和处理。 1. ETL概述 ETL(Extract...

    Netty 入门与实战:仿写微信 IM 即时通讯系统

    在本文中,我们将深入探讨Netty框架,并通过实战项目——仿写微信IM即时通讯系统,来深入了解其在高性能网络应用中的应用。Netty是Java领域中一个高效的异步事件驱动的网络应用程序框架,它为快速开发可维护的高性能...

    Netty 入门与实战:仿写微信 IM 即时通讯系统.rar

    Netty 入门与实战:仿写微信 IM 即时通讯系统,掘金小册子,netty教程。章节齐全无缺失,排版非常不错。 1.仿微信IM系统简介 1 2.Netty是什么? 2 3.服务端启动流程 8 4.客户端启动流程 11 5.实战:客户端与服务端双向...

    Netty入门与实战:仿写微信IM即时通讯系统

    ### Netty入门与实战:仿写微信IM即时通讯系统 #### 一、引言 随着移动互联网技术的飞速发展,即时通讯(IM)系统已成为人们日常生活中不可或缺的一部分。微信作为国内最受欢迎的即时通讯软件之一,其高效稳定的通信...

    Netty 入门与实战:仿写微信 IM 即时通讯系统.zip

    《Netty 入门与实战:仿写微信 IM 即时通讯系统》是一份专为初学者设计的高质量教程,旨在帮助读者快速掌握Netty框架并应用到实际的即时通讯系统开发中,如仿写微信IM系统。Netty是Java领域内广泛使用的高性能、异步...

    Netty 入门与实战:仿写微信 IM 即时通讯系统.pdf

    ### Netty 入门与实战:仿写微信 IM 即时通讯系统 #### 一、引言 随着移动互联网技术的飞速发展,即时通讯(IM)应用已成为人们日常生活中不可或缺的一部分。微信作为中国最成功的即时通讯软件之一,其背后的架构和...

    netty入门到精通.txt

    根据提供的文件信息“netty入门到精通”,我们可以深入探讨Netty框架的相关知识点,包括其基本概念、核心组件、应用场景以及如何逐步掌握这项技术。 ### Netty框架简介 Netty是一款高性能、异步事件驱动的网络应用...

    Netty 入门与实战

    5. **实战:构建客户端与服务端pipeline** Pipeline 是 Netty 的核心概念,它是一个处理链,包含多个ChannelHandler。每个Handler负责处理特定的事件或操作,如解码、编码、业务逻辑处理等。文件"11实战:构建...

    netty入门示例工程

    本工程采用maven+netty4.1.0+PrefixedStringDecoder+json技术,包括客户端和服务端。先运行服务端SampleServer,再去等客户端SampleClient。示例中发的是心跳包,其中消息格式定义为msgType + msgNo + content(json...

    netty入门进阶之前

    5. **内存管理与释放**: 文件"84-第2章_32-netty入门-bytebuf-内存释放-480P 清晰-AVC.Cover.jpg"可能涉及了Netty中如何有效地管理内存以及释放ByteBuf资源,这对于防止内存泄漏和提高系统稳定性至关重要。...

    Netty-入门Netty编码

    这个教程将引导我们入门 Netty 编码,让我们深入理解其核心概念和实际应用。 首先,Netty 的核心是其设计模式,即 Reactor 模式,也称为事件驱动模型。Reactor 模式允许 Netty 高效地处理大量并发连接,通过非阻塞 ...

    Netty+入门与实战:仿写微信+IM+即时通讯系统.rar

    《Netty+入门与实战:仿写微信+IM+即时通讯系统》是一本专注于使用Netty框架构建即时通讯系统的教程。Netty是一个高性能、异步事件驱动的网络应用框架,适用于开发服务器和客户端的Java应用。它极大地简化了网络编程...

    Netty 快速入门系列-源码

    Netty快速入门系列源码, 参考 https://blog.csdn.net/netcobol Netty是一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 Netty是...

    netty入门案例.zip

    这个“netty入门案例.zip”文件提供了一个简单的 Netty 应用示例,旨在帮助初学者快速理解并掌握 Netty 的基本概念和使用方法。下面将详细介绍这个入门案例中的关键知识点。 首先,Netty 的核心是其 ChannelHandler...

    netty 入门Reactor示例

    在学习"Netty入门Reactor示例"时,你可以按照以下步骤进行: 1. **创建服务器端:** - 首先,你需要创建一个ServerBootstrap实例,配置BossGroup和WorkerGroup。 - 然后,添加自定义的...

    netty入门Demo源码

    1.该项目基于maven构建,相关博客 ... 一个最简单的netty应用 使用:运行EchoServer,打开cmd命令...5.第四个示例 com.user_1 Netty将java对象作为数据的发送与接收升级版。将数据的预处理模块化提炼出来。 使用:同上

Global site tag (gtag.js) - Google Analytics