注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小葫芦君(汉斯的博客)

博客迁移到新博客:https://blog.ssxingshou.com

 
 
 

日志

 
 
关于我

小小葫芦商城,为您提供高品质的商品,一流的产品,一流的包装服务,一流的物流服务,放心购买

网易考拉推荐

Netty 4.0 新的特性及需要注意的地方 4  

2014-04-11 21:56:30|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

半关闭socket

TCP和SCTP允许用户关闭一个socket的出站流量而不用完全关闭它。这样的socket被称为“半关闭socket”,同时用户能够通过调用SocketChannel.shutdownOutput()方法来获取一个半关闭socket。如果一个远端关闭了出站通道,SocketChannel.read(..)会返回-1,这看上去并没有和一个关闭了的链接有什么区别。

3.x没有shutdownOutput()操作。同样,它总是在SocketChannel.read(..)返回-1的时候关闭链接。

要支持半关闭socket,4.0增加了SocketChannel.shutdownOutput()方法,同时用户能设置“ALLOW_HALF_CLOSURE”的ChanneOption来阻止Netty在SocketChannel.read(..)返回-1的时候自动关闭链接。

灵活的I/O线程分配

在3.x里,一个Channel是由ChannelFactory创建的,同时新创建的Channel会自动注册到一个隐藏的I/O线程。4.0使用新的名为EventLoopGroup的接口来替换ChannelFactory,它由一个或多个EventLoop来构成。同样,一个新的Channel不会自动注册到EventLoopGroup,但用户可以显式调用EventLoopGroup.register()来注册。

感谢这个变化(举例来说,分离了ChannelFactory和I/O线程),用户可以注册不同的Channel实现到同一个EventLoopGroup,或者同一个Channel实现到不同的EventLoopGroup。例如,你可以运行一个NIO服务器socket,NIO UDP socket,以及虚拟机内部的通道在同一个I/O线程里。在编写一个需要最小延迟的代理服务器时这确实很有用。

能够从一个已存在的jdk套接字上创建一个Channel

3.x没提供方法从已存在的jdk套接字(如java.nio.channels.SocketChannel)创建一个新的通道。现在你可以用4.0这样做了。

取消注册和重新注册一个Channel从/到一个I/O线程

一旦一个新的Channel在3.x里创建,它完全绑定到一个单一的I/O线程上,直到它底层的socket关闭。在4.0里,用户能够从I/O线程里取消注册一个Channel来完全控制它底层jdk套接字。例如,你能够利用Netty提供的高层次无阻塞I/O的优势来解决复杂的协议,然后取消注册Channel并且切换到阻塞模式来在可能的最大吞吐量下传输一个文件。当然,它能够再次注册已经取消了注册的Channel。

01java.nio.channels.FileChannel myFile = ...;
02java.nio.channels.SocketChannel mySocket = java.nio.channels.SocketChannel.open();
03  
04// Perform some blocking operation here.
05...
06  
07// Netty takes over.
08SocketChannel ch = new NioSocketChannel(mySocket);
09EventLoopGroup group = ...;
10group.register(ch);
11...
12  
13// Deregister from Netty.
14ch.deregister().sync();
15  
16// Perform some blocking operation here.
17mySocket.configureBlocking(false);
18myFile.transferFrom(mySocket, ...);
19  
20// Register back again to another event loop group.
21EventLoopGroup anotherGroup = ...;
22anotherGroup.register(ch);

调度任意的任务到一个I/O线程里运行

当一个Channel被注册到EventLoopGroup时,Channel实际上是注册到由EventLoopGroup管理EventLoop中的一个。EventLoop实现了java.utilconcurrent.ScheduledExecutorService接口。这意味着用户可以在一个用户通道归属的I/O线程里执行或调度一个任意的Runnable或Callable。随着新的娘好定义的线程模型的到来(稍后会介绍),它变得极其容易地编写一个线程安全的处理器。

01public class MyHandler extends ChannelOutboundMessageHandlerAdapter {
02    ...
03    public void flush(ChannelHandlerContext ctx, ChannelFuture f) {
04        ...
05        ctx.flush(f);
06  
07        // Schedule a write timeout.
08        ctx.executor().schedule(new MyWriteTimeoutTask(), 30, TimeUnit.SECONDS);
09        ...
10    }
11}
12  
13public class Main {
14    public static void main(String[] args) throws Exception {
15        // Run an arbitrary task from an I/O thread.
16        Channel ch = ...;
17        ch.executor().execute(new Runnable() { ... });
18    }
19}
  评论这张
 
阅读(627)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017