国产gaysexchina男同gay,japanrcep老熟妇乱子伦视频,吃奶呻吟打开双腿做受动态图,成人色网站,国产av一区二区三区最新精品

Netty 4.x 寫個時間服務器

2018-10-26 09:50 更新

寫個時間服務器

在這個部分被實現(xiàn)的協(xié)議是 TIME 協(xié)議。和之前的例子不同的是在不接受任何請求時他會發(fā)送一個含32位的整數(shù)的消息,并且一旦消息發(fā)送就會立即關閉連接。在這個例子中,你會學習到如何構建和發(fā)送一個消息,然后在完成時關閉連接。

因為我們將會忽略任何接收到的數(shù)據(jù),而只是在連接被創(chuàng)建發(fā)送一個消息,所以這次我們不能使用 channelRead() 方法了,代替他的是,我們需要覆蓋 channelActive() 方法,下面的就是實現(xiàn)的內容:

    public class TimeServerHandler extends ChannelInboundHandlerAdapter {

        @Override
        public void channelActive(final ChannelHandlerContext ctx) { // (1)
            final ByteBuf time = ctx.alloc().buffer(4); // (2)
            time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));

            final ChannelFuture f = ctx.writeAndFlush(time); // (3)
            f.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) {
                    assert f == future;
                    ctx.close();
                }
            }); // (4)
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }

1.channelActive() 方法將會在連接被建立并且準備進行通信時被調用。因此讓我們在這個方法里完成一個代表當前時間的32位整數(shù)消息的構建工作。

2.為了發(fā)送一個新的消息,我們需要分配一個包含這個消息的新的緩沖。因為我們需要寫入一個32位的整數(shù),因此我們需要一個至少有4個字節(jié)的 ByteBuf。通過 ChannelHandlerContext.alloc() 得到一個當前的ByteBufAllocator,然后分配一個新的緩沖。

3.和往常一樣我們需要編寫一個構建好的消息。但是等一等,flip 在哪?難道我們使用 NIO 發(fā)送消息時不是調用 java.nio.ByteBuffer.flip() 嗎?ByteBuf 之所以沒有這個方法因為有兩個指針,一個對應讀操作一個對應寫操作。當你向 ByteBuf 里寫入數(shù)據(jù)的時候寫指針的索引就會增加,同時讀指針的索引沒有變化。讀指針索引和寫指針索引分別代表了消息的開始和結束。

比較起來,NIO 緩沖并沒有提供一種簡潔的方式來計算出消息內容的開始和結尾,除非你調用 flip 方法。當你忘記調用 flip 方法而引起沒有數(shù)據(jù)或者錯誤數(shù)據(jù)被發(fā)送時,你會陷入困境。這樣的一個錯誤不會發(fā)生在 Netty 上,因為我們對于不同的操作類型有不同的指針。你會發(fā)現(xiàn)這樣的使用方法會讓你過程變得更加的容易,因為你已經習慣一種沒有使用 flip 的方式。

另外一個點需要注意的是 ChannelHandlerContext.write() (和 writeAndFlush() )方法會返回一個 ChannelFuture 對象,一個 ChannelFuture 代表了一個還沒有發(fā)生的 I/O 操作。這意味著任何一個請求操作都不會馬上被執(zhí)行,因為在 Netty 里所有的操作都是異步的。舉個例子下面的代碼中在消息被發(fā)送之前可能會先關閉連接。


    Channel ch = ...;
    ch.writeAndFlush(message);
    ch.close();

因此你需要在 write() 方法返回的 ChannelFuture 完成后調用 close() 方法,然后當他的寫操作已經完成他會通知他的監(jiān)聽者。請注意,close() 方法也可能不會立馬關閉,他也會返回一個ChannelFuture。

4.當一個寫請求已經完成是如何通知到我們?這個只需要簡單地在返回的 ChannelFuture 上增加一個ChannelFutureListener。這里我們構建了一個匿名的 ChannelFutureListener 類用來在操作完成時關閉 Channel。

或者,你可以使用簡單的預定義監(jiān)聽器代碼:

    f.addListener(ChannelFutureListener.CLOSE);

為了測試我們的time服務如我們期望的一樣工作,你可以使用 UNIX 的 rdate 命令

    $ rdate -o <port> -p <host>

Port 是你在main()函數(shù)中指定的端口,host 使用 locahost 就可以了。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號