Netty 5.X 官方指南翻译版2

继续翻译:http://netty.io/wiki/user-guide-for-5.x.htmlhtml

写一个Discard服务器

最简单的协议不是hello,而是DISCARDbootstrap

也就是说,忽略全部收到的数据,不返回任何响应。api

为了完成这个协议,你仅仅须要作的是忽略全部收到的数据,让咱们开始从handler实现开始,这个处理IO事件(来源于Netty).服务器

package io.netty.example.discard;网络

 

import io.netty.buffer.ByteBuf;多线程

 

import io.netty.channel.ChannelHandlerContext;app

import io.netty.channel.ChannelHandlerAdapter;socket

 

/**tcp

 * Handles a server-side channel.ide

 */

public class DiscardServerHandler extends ChannelHandlerAdapter { // (1)

 

    @Override

    public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)

        // Discard the received data silently.

        ((ByteBuf) msg).release(); // (3)

    }

 

    @Override

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)

        // Close the connection when an exception is raised.

        cause.printStackTrace();

        ctx.close();

    }

}

DiscardServerHandler extends ChannelHandlerAdapter是对ChannelHandler的一个实现ChannelHandler 提供了各类各样的事件方法可覆盖.

目前,继承 ChannelHandlerAdapter足够了 而不是本身实现接口里的方法。

 

咱们重写了channelRead() 事件方法,这个方法被接收到的消息调用,当从客户端里接收到新数据时。在这个例子当中,接收到的信息是 ByteBuf.

为了实现DISCARD协议,方法必须忽略收到的消息,ByteBuf 是一个计数器方式引用的对象,只有显式的经过release()方法才能够释放这个对象。请注意:这个handler有责任来释听任何传给本身的计数器引用的对象。

一般, channelRead() 方法用如下形式实现

 

@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {    try {        // Do something with msg    } finally {        ReferenceCountUtil.release(msg);    }}

 

 

The exceptionCaught() 事件方法:

当处理事件时,IO错误或者handler实现里有异常抛出。

大多数状况下,异常应该记录下来,而且相关的channel应该被关闭,尽管这个方法的实现能够不一样,这依赖于你想怎么处理。

好比,你也许想发送一个响应消息伴随错误码在关闭链接以前。

咱们已经实现了一半,剩下的是写main()方法来启动这个服务器。

package io.netty.example.discard;

 

import io.netty.bootstrap.ServerBootstrap;

 

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelOption;

import io.netty.channel.EventLoopGroup;

import io.netty.channel.nio.NioEventLoopGroup;

import io.netty.channel.socket.SocketChannel;

import io.netty.channel.socket.nio.NioServerSocketChannel;

 

/**

 * Discards any incoming data.

 */

public class DiscardServer {

 

    private int port;

 

    public DiscardServer(int port) {

        this.port = port;

    }

 

    public void run() throws Exception {

        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)

        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {

            ServerBootstrap b = new ServerBootstrap(); // (2)

            b.group(bossGroup, workerGroup)

             .channel(NioServerSocketChannel.class// (3)

             .childHandler(new ChannelInitializer<SocketChannel>() { // (4)

                 @Override

                 public void initChannel(SocketChannel ch) throws Exception {

                     ch.pipeline().addLast(new DiscardServerHandler());

                 }

             })

             .option(ChannelOption.SO_BACKLOG, 128)          // (5)

             .childOption(ChannelOption.SO_KEEPALIVEtrue); // (6)

 

            // Bind and start to accept incoming connections.

            ChannelFuture f = b.bind(port).sync(); // (7)

 

            // Wait until the server socket is closed.

            // In this example, this does not happen, but you can do that to gracefully

            // shut down your server.

            f.channel().closeFuture().sync();

        } finally {

            workerGroup.shutdownGracefully();

            bossGroup.shutdownGracefully();

        }

    }

 

    public static void main(String[] args) throws Exception {

        int port;

        if (args.length > 0) {

            port = Integer.parseInt(args[0]);

        } else {

            port = 8080;

        }

        new DiscardServer(port).run();

    }

}

1. NioEventLoopGroup 是一个多线程的事件循环,处理IO操做。

 Netty提供了各类各样的 EventLoopGroup实现来应对不一样种类的传输。

咱们在例子中实现服务器端的工程,所以两个NioEventLoopGroup 将会被使用,第一个,常常叫作boss,接收一个进来的链接,第二个,叫作worker,处理流量(接受的链接)一旦 boss接收了链接而且注册接收的链接到worker.多少线程被使用而且它们如何映射到建立的Channels依赖于 EventLoopGroup 实现,也能够经过构造器配置。

2. ServerBootstrap 是一个帮助类来安装服务器,你能够经过Channel来直接安装。

3. 尽管如此,要知道,这是一个单调的过程,大多数状况下不须要作这个。

4. 这里,咱们使用了 NioServerSocketChannel 类来初始化一个新的Channel来接收进来的链接。这个handler老是被新接受的channel调用。

5. ChannelInitializer是一个特别的handler,目的是帮助一个用户来配置一个新的Channel最有可能的就是你想配置 ChannelPipeline of the new Channel 经过增长新的句柄方法好比DiscardServerHandler 来实现你的网络工程。

6. 一旦工程变复杂了,你将增长更多的方法到pipeline上来,提取这个匿名类到一个底层类里。

7. 你也能够设置参数(特定于channel实现),咱们在写一个TCP/IP服务器,因此咱们能够设置socket的参数好比tcpNoDelay and keepAlive

8. 请参考ChannelOption 和特定的ChannelConfig实现来获取支持的选项说明。

9. 你意识到option()和childOption()?

10.  option()是为了NioServerSocketChannel ,这个接受链接。childOption()是为了channels(被父ServerChannel接受 ,在例子当中是 NioServerSocketChannel 

11. 咱们准备好了,剩下的就是绑定端口和启动服务器,这里,咱们绑定到8080端口,你能够调用bind()方法任意屡次只要愿意。(能够以不一样的绑定定制).

祝贺,你已经完成了第一个服务器的开发。

 

翻译 ok ok ok
理解 ok ok ok
相关文章
相关标签/搜索