netty 學習記錄二

來源:互聯網
上載者:User

標籤:netty

netty 最新版本是netty-5.0.0.Alpha1,去年10月份發布的,至今沒有發新版本,估計這個版本還是比較穩定. 整包下載,裡麵包含一個 netty-example-5.0.0.Alpha1-sources.jar檔案,提供了比較豐富的example例子,多看幾遍還是非常有收穫的,這裡記錄下.

先來看下channelHandler的兩個不同繼承:

方式一:直接從ChannelHandlerAdapter類裡繼承,讀取操作從channelRead方法裡執行

@Sharablepublic class EchoServerHandler extends ChannelHandlerAdapter {    private static final Logger logger = Logger.getLogger(            EchoServerHandler.class.getName());    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        ctx.write(msg);    }    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        ctx.flush();    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {        // Close the connection when an exception is raised.        logger.log(Level.WARNING, "Unexpected exception from downstream.", cause);        ctx.close();    }}

方式二:繼承至SimpleChannelInboundHandler類,讀取操作從方法messageReceived()裡執行

public class FactorialServerHandler extendsSimpleChannelInboundHandler<BigInteger> {private static final Logger logger = Logger.getLogger(FactorialServerHandler.class.getName());private BigInteger lastMultiplier = new BigInteger("1");private BigInteger factorial = new BigInteger("1");@Overridepublic void messageReceived(ChannelHandlerContext ctx, BigInteger msg)throws Exception {// Calculate the cumulative factorial and send it to the client.System.out.println("server msg:" + msg);lastMultiplier = msg;factorial = factorial.multiply(msg);ctx.writeAndFlush(factorial);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {Formatter fmt = new Formatter();logger.info(fmt.format("Factorial of %,d is: %,d", lastMultiplier,factorial).toString());fmt.close();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throws Exception {logger.log(Level.WARNING, "Unexpected exception from downstream.",cause);ctx.close();}}

區別可以從SimpleChannelInboundHandler類的解說文字看出,  

SimpleChannelInboundHandler : ChannelHandler which allows to explicit only handle a specific type of messages. 也就是可以操作指定類型的資訊.


接著看下 io.netty.example.factorial  這個包, 內容主要描述用戶端向服務端發數字,服務端返回數位階乘給用戶端,業務比較簡單.

編解碼操作涉及到的類,BigIntegerDecoder與NumberEncoder都是自訂的

pipeline.addLast("decoder", new BigIntegerDecoder());
pipeline.addLast("encoder", new NumberEncoder());

用戶端有這麼一段代碼:

ChannelFuture future = null;for (int i = 0; i < 4096 && next <= count; i++) {future = ctx.write(Integer.valueOf(next));next++;}if (next <= count) {assert future != null;future.addListener(numberSender);}ctx.flush();

服務端代碼:

@Overridepublic void messageReceived(ChannelHandlerContext ctx, BigInteger msg)throws Exception {// Calculate the cumulative factorial and send it to the client.System.out.println("server msg:" + msg);lastMultiplier = msg;factorial = factorial.multiply(msg);ctx.writeAndFlush(factorial);}

看了用戶端代碼覺得代碼在最後才flush的,所以服務端應該只收到一條訊息,messageReceived方法應該只調用一次,結果是messageReceived方法調用次數與用戶端發送次數一致. 有點奇怪. 看了下BigIntegerDecoder解碼類操作才探索服務端的確只收到了一條訊息,但是解碼器解碼成了多個對象(BigIntegerDecoder 類的decode方法被其父類ByteToMessageDecoder的callDecode方法反覆讀取同一條訊息的ByteBuf,直到讀完.),最後多次調用messageReceived方法.

以後如果自己寫編解碼類完全可以參考BigIntegerDecoder與NumberEncoder這兩個類來.


最後來看下http的幾個ChannelHandler

服務端:

 pipeline.addLast("decoder", new HttpRequestDecoder()); pipeline.addLast("aggregator", new HttpObjectAggregator(65536)); pipeline.addLast("encoder", new HttpResponseEncoder()); pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());

用戶端:

p.addLast("codec", new HttpClientCodec());p.addLast("aggregator", new HttpObjectAggregator(1048576));

剛看到時候覺得奇怪怎麼服務端與用戶端編解碼方式不一樣, 看下httpClientCoder類的說明(A combination of HttpRequestEncoder and HttpResponseDecoder which enables easier client side HTTP implementation),自然就懂了.

HttpObjectAggregator 瞭解這個handler先看段代碼:

@Override    protected void messageReceived(ChannelHandlerContext ctx, Object msg) {        if (msg instanceof HttpRequest) {                   }        if (msg instanceof HttpContent) {                   }    }

一般http請求或者響應,解碼器都將其解碼成為多個訊息對象,主要是httpRequest/httpResponse, httpcontent, lastHttpContent.然後反覆調用messageReceive這個方法,

HttpObjectAggregator 這個handler就是將同一個http請求或響應的多個訊息對象變成一個 fullHttpRequest完整的訊息對象.





netty 學習記錄二

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.