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
相關文章
相關標籤/搜索