Java遊戲服務器系列之Netty相關知識總結

一、簡介

Java的底層API逐漸復雜,而開發者面對的開發場景需求也在逐漸增大。如果直接針對底層API進行編程,無疑是耗時耗力的。這時就催生瞭極多的編程框架,這些框架隱藏瞭API實現的復雜細節,以最簡潔的方式給開發人員提供功能的實現接口。Netty就是一款針對於網絡鏈接的框架,他的出現讓服務器開發人員更加的集中關註於更多邏輯的實現,而不為瞭實現更好更多更穩定的鏈接而頭疼。Netty的核心功能基於NIO 實現。

二、Netty的應用場景

幾乎適用於所有的長短鏈接場景,由於Java應用的廣泛性,幾乎所有的互聯網公司或多或少的都會使用到。博主從事遊戲開發,可以說幾乎所有短鏈接遊戲服務器都是使用Netty開發,實效性要求比較高也有熱修復需求的服務器一般不會使用Java,目前采用更多的是C+Lua的組合方式。Java不可以熱修復是很多長鏈服務器不考慮java 的一個重要原因。

三、異步和事件驅動性

NIO 文章中強調瞭,這種模型的主要特地拿就是異步和事件驅動性,異步是服務器不需要一直等待鏈接輸入直到鏈接關閉。而是可以在某個特定的時候去相應鏈接的輸入,而特定的時候就是另一個事件驅動性,鏈接發生變化時,會產生一個事件,而NIO模型檢測到這個事件之後,會去相應這個事件的處理事件。

四、Netty核心組件

1.Channel:

Channel時Java-NIO的一個基本構造,它代表到一個實體的開放鏈接,如讀操作和寫操作,在NIO模型中也可以被理解成一個入站或者出站的數據載體,可以被關閉或者關閉。

2.回調 ChannelHandler:

一個回調就是一個方法,Netty提供瞭兩個子類,ChannelInboundHandlerAdapter 以及 ChannelOutboundHandlerAdapter ,這兩個子類分別可以應用於數據進站和出站時期,各種階段的回調,比如入站時Active方法,表明鏈接剛剛被建立起,代碼如下:

public class ConnectHandler extend ChannelInboundHandlerAdapter{
	@override
	public void ChannelActive(ChannelHandlerContext ctx){
		//數據入站回調子類被建立時調用,也就是鏈接建立時調用
		System.out.println("遠程客戶端 : "+ ctx.channel().remoteAddress() + '建立鏈接');
	}
}

不瞭解Netty的讀者看到這裡可能會有點疑惑,這個類應該怎麼用。這裡簡單的解釋一下:這種類會在Netty創建的時候註冊進服務中,然後在數據進站、出站的不同階段,調用這個類中不同的回調函數,以處理不同的開發需求。可以關註一下讀者其他的文章

3.Future:

jdk-Future:Java中提供瞭Future的實現,這種Futrue可以看作是一個異步操作結果的占位符。我們可以通過這個Future查詢到這個異步操作的結果,並進行一些處理。比如在操作失敗的時候拋出異常。但是jdk內置的Future的查詢隻能在某個時刻手動去查詢結果,或者直接阻塞這個異步操作,直到異步完成操作之後可以查詢Future的成功或者失敗。
ChannelFuture:Netty內部提供的Future實現類,很多異步操作在執行的時候都會返回一個ChannelFuture對象,我們可以針對這個ChannelFuture對象設置一些回調函數,比如重寫operationComplete()方法,這樣這個異步事件在完成的時候會自動調用這個方法,並且執行我們自己的處理邏輯。
接下來可以看一下ChannelFuture的應用實例,檢測Netty服務器鏈接遠程地址是否成功:

Channel channel = "";
//鏈接地址192.168.100.113 的7000端口
InetSocketAddress socketAddress = new InetSocketAddress("192.168.100.113",7000);
//管道綁定地址並返回一個ChannelFuture
ChannelFuture channelFuture = channel.connect(socketAddress);
//給ChannelFuture設置完成回調,判斷這個操作是否完成
channelFuture.addListener(new ChannelFutureListener(){
		@override
		public void operationComplete(ChannelFuture future){
			if(future.isSucess()){
				//創建一個字符串,並指定所使用的字符集,下面這種寫法是Netty中經常遇到的
				ByteBuf buffer = Unpooled.copiedBuffer("Hello",Charset.defaultCharset());
				//發送信息並且返回一個新的writeFuture,依舊可以根據這個writeFuture處理一些邏輯
				ChannelFuture writeFuture = future.channel().writeAndFlush(buffer);
			}else{
				//鏈接失敗則答應出失敗的消息
				Throwable cause = future.cause();
				cause.printStackTrace();
			}
		}
})

五、總結

Netty以一種異步事件驅動以及回調的方式,能幫我們快速完善服務器處理數據的進出,以及各個流程細節中的處理邏輯。極大的精簡瞭服務器開發人員在,鏈接處理,數據出入方面的開發工作。是一個及其易用且穩定的網絡開發框架。

到此這篇關於Java遊戲服務器系列之Netty相關知識總結的文章就介紹到這瞭,更多相關Java Netty內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: