路線提升篇netty in action中文版第四章transports傳輸_第1頁
路線提升篇netty in action中文版第四章transports傳輸_第2頁
路線提升篇netty in action中文版第四章transports傳輸_第3頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、NettyInAction章:Transports(傳輸本章內(nèi)Transports(傳輸NIO(non-blocking IIO), OIO(Old IO,blocking IO), Local(本地), Embedded(APIs(接口網(wǎng)絡(luò)應(yīng)用程序一個很重要的工作是傳輸數(shù)據(jù)。傳輸數(shù)據(jù)的過程不一樣取決是使用哪種交通工具,但是傳輸?shù)姆绞绞且粯拥模憾际且宰止?jié)碼傳輸。Java開發(fā)網(wǎng)絡(luò)程序傳輸數(shù)據(jù)的過程和方式是被抽象了的, 不需要關(guān)注底層接口,只需要使用JNettyInAction章:Transports(傳輸本章內(nèi)Transports(傳輸NIO(non-blocking IIO), OIO(Old

2、 IO,blocking IO), Local(本地), Embedded(APIs(接口網(wǎng)絡(luò)應(yīng)用程序一個很重要的工作是傳輸數(shù)據(jù)。傳輸數(shù)據(jù)的過程不一樣取決是使用哪種交通工具,但是傳輸?shù)姆绞绞且粯拥模憾际且宰止?jié)碼傳輸。Java開發(fā)網(wǎng)絡(luò)程序傳輸數(shù)據(jù)的過程和方式是被抽象了的, 不需要關(guān)注底層接口,只需要使用Java PI或其他網(wǎng)絡(luò)框架如etty就能達到傳輸數(shù)據(jù)的目的。發(fā)送數(shù)據(jù)和接收數(shù)據(jù)都是字節(jié)碼。otigore,otigess。本章將介紹 的PI以及如何使用它們,會拿etty的PI和Java的PI做比較來告訴你為什么etty可以更容易的使用。本章也提供了一些優(yōu)質(zhì)的用例代碼,以便最佳使用etty。使用

3、etty不需要其他的網(wǎng)絡(luò)框架或網(wǎng)絡(luò)編程經(jīng)驗,若有則只是對理解etty有幫助,但不是必要的。下面讓 來看看真是世界里的傳輸工作。案例研究:切換傳輸方為了讓你想象如,我會從一個簡單的應(yīng)用程序開始,這個應(yīng)用程序什么都不做,只是接受客戶端連接并發(fā)送“Hi!”字符串消到客戶端,發(fā)送完了就斷開連接。我不會詳細講解這個過程的實現(xiàn),它只是一個例子使用Java的I/O和不用Netty實現(xiàn)這個例子,下面代碼是使用阻塞IO實現(xiàn)的例子package import import import import import * Blocking networking without * author *public cla

4、ss PlainOioServer public void port) throws Exception /bind server to final ServerSocket socket = new try /accept final Socket ntSocket = ln(Accepted connection from + /create new thread to handle new Thread(new Runnable() 目錄案例研究切換傳輸方使用Java的IO和Netty中使用IO和Netty中實現(xiàn)異步支Transport Netty包含的傳輸實NIO - Nonblock

5、ing OIO -Old blocking Local- InVM Embedded每種傳輸方式在什么時候使public void run() OutputStream out = /write message to connected 上面的方式很簡潔,但是這種阻塞模式在大連接數(shù)的情況就會有很嚴,如客戶端連接超時,服務(wù)器響應(yīng)嚴重延遲。為了解決種情況可以使用異步網(wǎng)絡(luò)處理所有的并發(fā)連接,但問題在于NIO和OIO的API是完全不同的,所以一個用OIO開發(fā)的網(wǎng)絡(luò)應(yīng)用程想要使用NIO重構(gòu)代碼幾public void run() OutputStream out = /write message to

6、connected 上面的方式很簡潔,但是這種阻塞模式在大連接數(shù)的情況就會有很嚴,如客戶端連接超時,服務(wù)器響應(yīng)嚴重延遲。為了解決種情況可以使用異步網(wǎng)絡(luò)處理所有的并發(fā)連接,但問題在于NIO和OIO的API是完全不同的,所以一個用OIO開發(fā)的網(wǎng)絡(luò)應(yīng)用程想要使用NIO重構(gòu)代碼幾乎是重新開發(fā)下面代碼是使用Java NIO實現(xiàn)的例package import import import import import import import import * Asynchronous networking without * author *public class PlainNioServer pub

7、lic void port) throws Exception ln(Listening for connections on port + /open ndles Selector selector = /open ServerSocketChannel serverChannel = /get ServerSocket serverSocket = /bind server to serverSocket.bind(new /set to non-/register ServerSocket to selector and t it erested in new accepted serv

8、erChannel.register(selector, final ByteBuffer msg = while (true) /Wait for new t are ready for s. This will block until something n = if (n 0) /Obtain all SelectionKey t received Iterator iter = while (iter.hasNext() SelectionKey key = try /Check if event was because new nt ready to get out.write(Hi

9、!rn.getBytes(Charset.forName(UTF-/close connection once message written and catch(IOException try catch (IOException e1) ).start();/start thread to begin catch(Exception if (key.isAcceptable() ServerSocketChannel server = (ServerSocketChannel) SocketChannel nt = ln(Accepted connection from + /Accept

10、 nt and register it to nt.register(selector, SelectionKey.OP_WRITE, /Check if event was because socket is ready to write if (key.isWritable() SocketChannel nt = (SocketChannel) if (key.isAcceptable() ServerSocketChannel server = (ServerSocketChannel) SocketChannel nt = ln(Accepted connection from +

11、/Accept nt and register it to nt.register(selector, SelectionKey.OP_WRITE, /Check if event was because socket is ready to write if (key.isWritable() SocketChannel nt = (SocketChannel) ByteBuffer buff = (ByteBuffer) /write o connected while (buff.hasRemaining() if nt.write(buff) = 0) nt.close();/clos

12、e catch (Exception e) 如你所見,即使它們實現(xiàn)的功能是一樣,但是代碼完全不同。下用Netty來實現(xiàn)相同的功能4.1.2 Netty中使用I/O和下面代碼是使用Netty作為網(wǎng)絡(luò)框架編寫的一個阻塞IOpublic ettyOioServer public void port) throws Exception final ByteBuf buf = uffer(Unpooled.copiedBuffer(Hi!rn, /事件循環(huán)EventLoopGroup group = new try /用來引導服務(wù)器配ServerBootstrap b = new /使用OIO阻塞模ew

13、 /指定ChannelInitializer初始化.childHandler(new ChannelInitializer() protected void initChannel(Channel ch) throws Exception /添加一個“入站”handler到ch.pipeline().addLast(new ChannelInboundHandlerAdapter() public void channelActive(ChannelHandlerContext ctx) throws Exception /連接后,寫消息到客戶端,寫完后便關(guān)閉連package netty.in

14、.action; import .InetSocketAddress; import import import import import import import import import import import import import ty.util.CharsetUtil; /綁定服務(wù)器接受連ChannelFuture f = catch (Exception e) 所有資上面代碼實現(xiàn)功能一樣,但結(jié)構(gòu)清晰明了,這只是Netty的優(yōu)勢之一4.1.3 Netty中實現(xiàn)異步支持下面代碼是使用Netty實現(xiàn)異步,可以看出/綁定服務(wù)器接受連ChannelFuture f = catc

15、h (Exception e) 所有資上面代碼實現(xiàn)功能一樣,但結(jié)構(gòu)清晰明了,這只是Netty的優(yōu)勢之一4.1.3 Netty中實現(xiàn)異步支持下面代碼是使用Netty實現(xiàn)異步,可以看出使用Netty由OIO切換到NIO是非常的方便public ettyNioServer public void port) throws Exception final ByteBuf buf = Hi!rn, / 事件循環(huán)EventLoopGroup group = new try / 用來引導服務(wù)器配ServerBootstrap b = new / 使用NIO異步模ew / 指定ChannelInitializ

16、er初始化.childHandler(new ChannelInitializer() protected void initChannel(SocketChannel ch) throws Exception / 添加一個“入站”handler到ChannelPipeline ch.pipeline().addLast(new ChannelInboundHandlerAdapter() public void channelActive(ChannelHandlerContext ctx) throws Exception / 連接后,寫消息到客戶端,寫完后便關(guān)閉連/ 綁定服務(wù)器接受連Ch

17、annelFuture f = catch (Exception e) 所有資因為Netty使用相同的API來實現(xiàn)每個傳輸,它并不關(guān)心你使用什么來實現(xiàn)。Netty通過操作Channel接口和ChannelPipelineChannelHandler來實現(xiàn)傳輸4.2 Transport 傳輸API是Channel接口,它用于所有出站的操作。Channel接口的類層次結(jié)構(gòu)如package netty.in.action; import import import import import import import import import import import import impor

18、t ty.util.CharsetUtil; import .InetSocketAddress; 如上圖所示,每個Channel都會分配一個ChannelPipeline和ChannelConfig。ChannelConfig負責設(shè)置配置,并允許在運行期間更它們。傳輸一般有特定的配置設(shè)置,只作用于傳輸,沒有其他的實現(xiàn)。ChannelPipeline容納了使用的ChannelHandler實例,這如上圖所示,每個Channel都會分配一個ChannelPipeline和ChannelConfig。ChannelConfig負責設(shè)置配置,并允許在運行期間更它們。傳輸一般有特定的配置設(shè)置,只作用于

19、傳輸,沒有其他的實現(xiàn)。ChannelPipeline容納了使用的ChannelHandler實例,這 現(xiàn)可以使用ChannelHandler做下面一些事情傳輸數(shù)據(jù)時,將數(shù)據(jù)從一種格式轉(zhuǎn)換到另異常Channel變?yōu)橛行Щ驘o效時獲得通Channel或從EventLoop中注銷時獲得通通知用戶特定事這些ChannelHandler實例添加到ChannelPipeline中,在ChannelPipeline中按順序逐個執(zhí)行。它類似于一個鏈條,有使用過Servlet讀者可能會更容易理解ChannelPipeline實現(xiàn)過濾器模式,這意味連接不同的ChannelHandler并處理經(jīng)過ChannelPip

20、eline的數(shù)據(jù)或件??梢园袰hannelPipeline想象成UNIX管道,它允許不令鏈(ChannelHandler相當于命令)。你還可以在運行時根據(jù)需要添ChannelHandler實例到ChannelPipeline或從ChannelPipeline中刪除,這能幫構(gòu)建高度靈活的Netty程序。此外指定ChannelPipeline和ChannelConfig,你能在Channel自身上進行操作。Channel提供了很多方法,如下列eventLoop(),返回分配給Channel的pipeline(),返回分配給Channel的iive(),返回Channel是否激活,已激活說明連接對l

21、ocalAddress(),返回已綁定的本地remoteAddress(),返回write(),寫數(shù)客戶端,數(shù)據(jù)通過ChannelPipeline傳輸過后面會越來越熟悉這些方法,現(xiàn)在只需要記的操作都是在相同的接口上運行,Netty的高靈活性讓你可以以不同的傳輸實現(xiàn)進行構(gòu)寫數(shù)據(jù)已連接客戶端可以調(diào)用Channel.write()方法,如下代碼Channel channel = /Create t holds o ByteBuf buf = Unpooled.copiedBuffer(your data, /Write ChannelFuture cf = /Add ChannelFutureLis

22、tener to get notified after write cf.addListener(new ChannelFutureListener() public plete(ChannelFuture future) /Write operation completes without if cs() ln(.Write else /Write operation completed but because of ln(.Write ae是線程安全(trea-safe)的,它可以被多個不同ae是線程安全(trea-safe)的,它可以被多個不同的線程安全的操作,在多線程環(huán)境下,所有的方法

23、都是安全的。正因為 ae是安全的,對Cae的,并在學習的時候使用它寫入數(shù)據(jù)到已連接的客戶端,使用多線程也是如此。下面代碼是一個簡單的多線程例子:final Channel channel = /Create t holds o final ByteBuf buf = Unpooled.copiedBuffer(your /Create Runnable which writes o Runnable writer = new Runnable() public void run() /Obtain reference to the Executor which uses threads to

24、execute Executor executor = / write in one /Hand over write task to executor for / write in another /Hand over another write task to executor for 此外,這種方法保證了寫入的消息以相同的順序通過寫入它們的方法。想了解所有方法的使用可以參考Netty API4.3 Netty包含的傳輸實etty自帶了一些傳輸協(xié)議的實現(xiàn),雖然沒有支持所有的傳輸協(xié)議,但是其自帶的已足夠來使用。etty應(yīng)用程序的傳輸協(xié)議賴于底層協(xié)議,本節(jié)學習etty中的傳輸協(xié)議。Netty中

25、的傳輸方式有如下幾種 Eee,io.ett.cae.eee,嵌入傳輸,它允許在沒有真正網(wǎng)絡(luò)的中使用aeaer,可以非常有用的來測試aeaer的實現(xiàn)。4.3.1NIO-NonblockingNIO傳輸是目前最常用的方式,它通過使用選擇器提供了完全異步的方式操作所有的I/O,NIO從Java 1.4才被提供。NIO中一個通道或獲得某個通道的改變的狀態(tài),通道狀態(tài)有下面幾種改變一個新的Channel被接受并已準備Channel連接完處理完改變的狀態(tài)后需重新設(shè)置他們的狀態(tài),用一個線程來檢查是否有已準備好的ae,如果有則執(zhí)行相關(guān)事件。在這里可能只同時一個的事件而忽略其他的。選擇器所支持的操作在SeectioKey中定義,具體如下:OP_WRITE,寫入數(shù)據(jù)到通道時得到通Netty中的NIO傳輸就是基于這樣的模型來接收和發(fā)送數(shù)據(jù),通過封裝將自己的接口提供給用戶使用,這完全隱藏實

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論