SpringBoot + Netty 實現 Json字符串 的傳輸(一)

怎樣把一個Json字符串傳輸到網絡的另一端?

1. 確定傳輸協議:

    我們在進行網絡編程的時候,首先要確定的就是傳輸協議,常見的傳輸協議就是UDP和TCP。

    我採用的是TCP,因爲,TCP可以保證傳輸數據的可靠性。

2. 應用層協議。

    爲啥應用層還要定義一次協議呢?

    因爲,應用層都是面向對象的編程,而傳輸層面向的是二進制的數據流,所以,我們要定義協議完成數據對象與二進制數據流直接的轉換。

    當然,通常來說,傳輸Json串,有兩種方案可以實現:

    A. 以換行符作爲分隔符傳輸Json串,換句話說,就是在每個Json串後面追加一個換行符進行數據傳輸。這樣的話,接收端在接收數據的時候,發現換行符,就意味着一個Json串接收完畢了。

    B. 採用添加包頭(或者包頭+包尾)的方式傳輸Json串,包頭中可以保存Json串的一些有關傳輸的信息,包尾可以添加分隔符(可以不添加包尾數據)。

    我們知道,Java語言是要先定義類然後才能創建對應的對象的,如果Json串被接收之後,如果想要反序列化成爲Java對象,只有兩種方案:一種是使用Map存放Json的屬性信息,另一種是自定義Class與Json對應,然後反序列化得到對象。這第二種方案裏面,有一個關鍵的內容是,我們要先知道Json與Class的映射關係才能將Json反序列化成對象,很顯然,上面說的A用換行符傳輸Json串就不適用了,因爲,這種方式中,我們無法拿到Json與Class的映射關係(當然,如果Json串裏面包含這種關係,是沒有什麼問題的,我們談論的思想是想盡量將Json與傳輸本身分離開來)。

    下面,我們做一下小結:

    方案A傳輸Json可以將Json映射成Map對象進行數據的訪問;

    方案B傳輸Json可以在包頭中定義Class的編號,接收端通過編號找到對應Class類,反序列化成對象進行數據訪問。

    我打算使用後者寫一個Demo。

3. BIO還是NIO

    BIO雖然編程模型較爲簡單,但是,這種IO的操作方式,早已淡出了我的視線,IO密集型的程序,BIO會使得大量的線程處於阻塞狀態,這對於我這種強迫症患者來講,是不可容忍的。我的理念裏面,多線程的最佳使用場景是運用在CPU密集型的程序當中。所以,爲了讓一條線程能夠管理更多的連接,進行更多的IO操作,我還是選擇的NIO(當然,還有一個原因是因爲NIO有框架可以簡化編程)。

4. 選擇框架,毫無疑問,衆所周知,SpringBoot + Netty 。

5. 聊一下協議中的數據格式:

頭部:4bytes           | 2bytes    | 2bytes    | 2bytes               | 2bytes

          0xFFFE0608 | Version   | Channel | Command         | Length

          開始分隔符    | 協議版本 | 頻道號   | 命令字(類ID)| 包體長度

包體:Xbytes

          長度與包頭部分定義的長度一致,採用UTF-8編碼進行轉換

包尾:4bytes

          0xFFFE0806

          結尾分隔符

其中,包尾可以不使用的,我這裏添加包尾,是想在接收端遇到碎包時,可以通過包尾分隔符跳過碎包的數據,或者爲接收端提供另只用解析報文的方式。這種情況在Demo中並沒有進行實現,所以,包尾部分,屬於備選信息。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章