天天看點

netty系列之:在netty中使用protobuf協定

簡介

定義protobuf

定義handler

設定channelpipeline

建構client和server端并運作

總結

netty中有很多适配不同協定的編碼工具,對于流行的google出品的protobuf也不例外。netty為其提供了protobufdecoder和protobufencoder兩個工具還有對應的frame detection,接下來我們會通過一個例子來詳細講解如何在netty中使用protobuf。

我們舉個最簡單的例子,首先定義一個需要在網絡中進行傳輸的message,這裡我們定義一個student對象,他有一個age和一個name屬性,如下所示:

使用下面的指令,對其進行編譯:

可以看到生成了3個檔案,分别是student,studentorbuilder和studentwrapper。其中student和studentorbuilder是我們真正需要用到的對象。

在handler中,我們主要進行對消息進行處理,這裡我們在clienthandler中進行消息的建構和發送,studentclienthandler繼承simplechannelinboundhandler并重新channelactive方法, 在該方法中我們使用protobuf的文法,建構一個新的student執行個體,并給他設定好age和name兩個屬性。

然後使用ctx.write和ctx.flush方法将其發送到server端:

studentserverhandler也是繼承simplechannelinboundhandler,并重寫channelread0方法,當server端讀取到student消息的時候,日志輸出,并将其回寫到channel中,供clienthandler讀取:

當client讀取到消息之後,直接日志輸出,不再做進一步處理,到此,一輪client和server端的互動就完成了:

在上一節,不管是在studentclienthandler還是在studentserverhandler中,我們都假設channel中傳遞的對象就是student,而不是原始的bytebuf。這是怎麼做到的呢?

這裡我們需要使用到netty提供的frame detection,netty為protobuf協定專門提供了protobufdecoder和protobufencoder,用于對protobuf對象進行編碼和解碼。

但是這兩個編碼和解碼器分别是messagetomessageencoder和messagetomessagedecoder,他們是消息到消息的編碼和解碼器,是以還需要和frame detection配合使用。

netty同樣提供了和protobuf配合使用的frame detector,他們是protobufvarint32framedecoder和protobufvarint32lengthfieldprepender。

varint32指的是protobuf的編碼格式,第一個位元組使用的是可變的varint。

有了frame detector和編碼解碼器,我們隻需要将其順序加入channelpipeline即可。

在用戶端,studentclientinitializer繼承自channelinitializer,我們需要重寫其initchannel方法:

在伺服器端,同樣studentserverinitializer也繼承自channelinitializer,也需要重寫其initchannel方法:

這樣channelpipeline也設定完成了。

最後好做的就是建構client和server端并運作,這和普通的netty用戶端和伺服器端并沒有什麼差別:

建構studentclient:

建構studentserver:

運作可得:

可見student消息已經發送和接收成功了。

netty提供了很多和協定适配的工具類,這樣我們就可以專注于業務邏輯,不需要考慮具體的編碼轉換的問題,非常好用。

最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

歡迎關注我的公衆号:「程式那些事」,懂技術,更懂你!