当前位置:首页 > 开发 > 编程语言 > 网络编程 > 正文

Netty学习笔记

发表于: 2013-12-25   作者:bylijinnan   来源:转载   浏览:
摘要: 本文是阅读以下两篇文章时: http://seeallhearall.blogspot.com/2012/05/netty-tutorial-part-1-introduction-to.html http://seeallhearall.blogspot.com/2012/06/netty-tutorial-part-15-on-channel.html 我的一些笔记 ===

本文是阅读以下两篇文章时:
http://seeallhearall.blogspot.com/2012/05/netty-tutorial-part-1-introduction-to.html
http://seeallhearall.blogspot.com/2012/06/netty-tutorial-part-15-on-channel.html
我的一些笔记

=================笔记1

static class ServerDateHandler extends SimpleChannelHandler {
 Random random = new Random(System.nanoTime());
 public void messageReceived(ChannelHandlerContext ctx,MessageEvent e) throws Exception {
  Date date = (Date)e.getMessage();
  // Here's the REALLY important business service at the end of the pipeline
  long newTime = (date.getTime() + random.nextInt());
  Date newDate = new Date(newTime);
  slog("Hey Guys !  I got a date ! [" + date + "] and I modified it to [" + newDate + "]");
  // Send back the reponse
  Channel channel = e.getChannel();
  ChannelFuture channelFuture = Channels.future(e.getChannel());
  ChannelEvent responseEvent = new DownstreamMessageEvent(channel, channelFuture, newDate, channel.getRemoteAddress());
  ctx.sendDownstream(responseEvent);
  // But still send it upstream because there might be another handler
  super.messageReceived(ctx, e);
 } 
}

为什么不直接这样:ctx.getChannel().write(newDate)?
作者是这样解释的:
If we wrote to the Channel directly, it would start from the "top" of the pipeline 
and might be pushed through handlers that are not indented to be called with the return Date.

不是很理解,看看源码:

e.getChannel().write最终调用DefaultChannelPipeline,从最后一个ChannelHandler(tail)往前,
消息会经过所有的DownstreamHandler:
    public void sendDownstream(ChannelEvent e) {
        DefaultChannelHandlerContext tail = getActualDownstreamContext(this.tail);
        if (tail == null) {
            try {
                getSink().eventSunk(this, e);
                return;
            } catch (Throwable t) {
                notifyHandlerException(e, t);
                return;
            }
        }
        sendDownstream(tail, e);
    }



ctx.sendDownstream则只从当前的ChannelHandler往前走,也就是,
只有在当前ChannelHandler之前的ChannelHandler,才会经过:
        public void sendDownstream(ChannelEvent e) {
            DefaultChannelHandlerContext prev = getActualDownstreamContext(this.prev);
            if (prev == null) {
                try {
                    getSink().eventSunk(DefaultChannelPipeline.this, e);
                } catch (Throwable t) {
                    notifyHandlerException(e, t);
                }
            } else {
                DefaultChannelPipeline.this.sendDownstream(prev, e);
            }
        }

这样可以避免消息穿过不必要的ChannelHandler,当然,如果清楚地知道,
那些“不必要的ChannelHandler”不会修改消息,
那直接e.getChannel().write也未尝不可

=================笔记2
a Channel provides the interface to connect and write to the destination represented by the Channel. 
No read ? you might ask ? Nope. Remember, it's like the asynchronous getWidgetCountmethod mentioned above. 
There's no return value.

Channel没有read方法?那怎么读取消息?
原来,读取到的消息,都封装在MessageEvent里面了,
它帮你读取好了,再fireMessageReceived通知你处理——这就是所谓的“异步”。详见NioWorker的read

=================笔记3
In the server, there is one boss thread allocated per listening socket.
For example, if you opened two server ports such as 80 and 443, you will have two boss threads.
In the client, there is only one boss thread*




=================笔记4
Please note that this decoder must be used with a proper FrameDecoder such as DelimiterBasedFrameDecoder 
if you are using a stream-based transport such as TCP/IP.
 // Decoders
pipeline.addLast("frameDecoder", new DelimiterBasedFrameDecoder(80, Delimiters.lineDelimiter()));
pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));


为什么 StringDecoder要和FrameDecoder在一起使用?
因为任何消息的到来,刚开始都是byte[],如何进行“分段”( segment the byte stream,
分段方案有很多,例如length+content、或者delimiter等等),是第一个ChannelHandler的工作。
StringDecoder并没有“分段”的功能,它没有extends FrameDecoder
因此要在它前面安排一个FrameDecoder

=================笔记5
自定义delimiter:
ChannelBuffer delimiter = ChannelBuffers.wrappedBuffer("THEBIG-D".getBytes())


=================笔记6
In the server, there is one boss thread allocated per listening socket. In the client, there is only one boss thread*

1.The boss thread can be released when there is no work to do and is created lazily, 
but it may be more efficient to pool a small number of threads than 
create a new one when required and destroying it when idle. 
2.It is possible that one might want to create several different channel factories 
and rather than giving each one their own boss pool, they can all share one.

为什么client只需要一个boss thread但仍然采用Excutor?
除了作者说的两个原因之外,我认为还有个原因是出于扩展性的考虑,允许你传入不同的Executor

=================笔记7
The Worker Threads: Worker threads perform all the asynchronous I/O. They are not general purpose threads and developers should take precautions not to assign unrelated tasks to threads in this pool which may cause the threads to block, be rendered unable to perform their real work which in turn may cause deadlocks and an untold number of performance issues.

第一次看这段话不理解,现在看来作者的意思应该是:worker thread是专门为IO而生,且是异步的。开发者不应该把其他工作交给worker thread运行

=================笔记8

Once you're done with a ChannelFactory, be sure to callreleaseExternalResources() on the factory. This will ensure that all its resources are released. 

要记得调用 ChannelFactory的releaseExternalResources来释放资源:
 bootstrap.releaseExternalResources();
public class Bootstrap...{
    public void releaseExternalResources() {
        ChannelFactory factory = this.factory;
        if (factory != null) {
            factory.releaseExternalResources();
        }
    }
}



Netty学习笔记

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
这次实验要用netty实现一个EchoServer,Echo Protocol 的定义在这里http://tools.ietf.org/html/rfc
这次实现一个TimeServer和一个TimeClient 主要功能就是 Client连接到Server后 Server立即返回一个32
转自http://hongweiyi.com/2014/01/netty-4-x-thread-model/ Netty 4.x学习笔记 – 线程模型 1、前
Netty是一个基于JAVA NIO类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、
1、简介 Java1.4提供了NIO使开发者可以使用Java编写高性能的服务端程序,但使用原生的NIO API就像Li
首先我们先来看serverchannel的类继承层次,然后再一个一个的研究。 现在我们来挨个的介绍各个类。
今天我来来看一下整个ChannelConfig的类的继承层次: 整个类结构来说还是比较好理解的,我就将作者的
netty里面ChannelEvent是非常重要的一个概念,在这个里面我们来重点分析一下。 ChannelEvent应该是n
背景 最忌工作中接触到Netty相关应用场景,之前看过mima的部分源码,所以最近看了Netty的部分源码和
注:本文翻译自Netty官方网站,地址:https://netty.io/ Netty介绍 Netty是一个异步事件驱动的网络
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号