Akka邊學邊寫(2)-- Echo Server
EchoServer
上篇文章裡,我們用Akka寫了一個簡單的HelloWorld例子,對Akka(以及Actor模式)有了初步的認識。本文將用Akka寫一個EchoServer,看看在Actor的世界裡,如何使用TCP協議。
Github專案
照例,EchoServer的程式碼被放在了Github上。EchoServer比HelloWorld稍微複雜一點,一共有三個類,如下圖所示:
Main
這次先從主類入手:
main()方法的第一行建立了一個Actor系統,名字為mySystem。接下來的四行程式碼,請看下面的詳細解釋。
TCP Manager
Akka將整個TCP層抽象為一個Actor,這個Actor就是TCP Manager。在main()方法的第二行程式碼裡,我們給Actor系統新增了一個TCP Manager,並和它的經紀人取得了聯絡:
ActorRef tcpManager = Tcp.get(mySystem).getManager();
現在我們的Actor系統看起來是這樣:
Props
Props應該是Properties的縮寫,它的作用是告訴Actor系統如何建立一個Actor。Props提供了四個工廠方法來建立Props例項,如下所示:
public static Props create(Class<?> type, Object[] os)
public static <T extends Actor> Props create(Class<T> type, Creator<T> crtr)
public static <T extends Actor> Props create(Creator<T> crtr)
public static Props create(Class<?> type, Seq<Object> seq)
main()方法的第三行使用了上面的第一個工廠方法,這個工廠方法有兩個引數:一個Class,和一個陣列(實際上是vararg)。第一個參數列示Actor的class,第二個引數是傳遞給Actor建構函式的引數。這樣,Actor系統就知道如何根據Props建立(用反射呼叫建構函式)一個Actor例項。main()方法的第四行建立了一個Accepter,起名為accepter。Accepter需要用到tcpManager,這也是我們將tcpManager當做第二個引數傳遞給Props.create()方法的緣故。現在Actor系統變成了下面這樣(我用虛線箭頭來表示Actor之間的依賴關係):
main()方法的第五行給accepter發了一個訊息:整數12345。告訴它繫結埠12345,開始監聽TCP連線,準備echo服務。
Accepter
Accepter負責監聽埠,然後把收到的tcp連線交給Handler去處理。Accepter稍微有點複雜,下面是全部程式碼:
建構函式是為了建立對tcpManager的依賴,下面詳細介紹onReceive()方法:
- 如果收到的訊息是Integer型別(port),我們給tcpManager傳送繫結訊息,通知它繫結某個埠。
- 如果tcpManager成功繫結埠,它會迴應已繫結訊息(Bound)。
- 否則,迴應繫結失敗訊息(CommandFailed),accepter通過呼叫getContext().stop()方法結束自己。
- 成功繫結埠後,如果有連線到達,則會收到Connected訊息。accepter通過呼叫getContext().actorOf()建立一個Handler,然後把它註冊給tcpManager。之後tcpManager就會把與這個連線相關的訊息發給handler,換句話說,這個連線被handler接管。
Actor之間的父子關係
在Actor系統內部,Actor們之間並不是只有簡單的依賴(或引用)關係,而是可以形成父子關係:Actor可以建立子Actor,然後把子任務分配給它們去處理。一個Actor的Children是通過它的context來管理的,上面程式碼中,accepter通過getContext()來獲得它自己的context,然後通過呼叫context的actorOf()方法建立子Actor。假設現在有兩個客戶端連線到了我們的echo伺服器,那麼整個Actor系統將是下面這樣(Actor系統內的實線箭頭表示父子關係):
Handler
最後一個類是Handler,它比較簡單,程式碼如下所示:
Handler只處理兩種訊息:
- Received訊息告訴handler有訊息到達,因為是echo伺服器,所以並不關心到達的訊息裡面是什麼內容。getSender()方法可以得到訊息的傳送者,也就是tcpManager。然後給tcpManager發一條Write訊息,告訴它把資料原封不動的寫回給客戶端。
- ConnectionClosed告訴handler連線已經斷開,handler通過呼叫context的stop()方法結束自己短暫的生命。
測試EchoServer
啟動EchoServer,然後可以通過telnet命令進行測試,這裡就不詳細說明了。
結論
要想用Akka寫一個echo伺服器,還是挺難的,需要了解Akka的很多方面。但是相對於Socket,或者NIO來說,Akka版的echo伺服器顯然更簡單。
相關文章
- 一邊寫作業一邊聽雞湯(2)
- iOS 邊學邊記iOS
- thinkphp3.23寫的個人部落格,邊學邊改吧!PHP
- 邊學邊玩CSS GridCSS
- pytest 邊學邊用(二)
- 邊寫 Javascript 程式碼邊玩遊戲 – WarriorJSJavaScript遊戲JS
- 邊學邊寫——母函式及其在中學數學競賽中的運用(一)函式
- 【從0到1學習邊緣容器系列2】之 邊緣應用管理
- [邊學邊練]用簡單例項學習React單例React
- 【Python | 邊敲邊學邊記】第一次:正規表示式Python
- 【Python | 邊學邊敲邊記】第三次:URL去重策略Python
- 【Python | 邊學邊敲邊記】第四次:初識爬蟲框架ScrapyPython爬蟲框架
- 邊下載邊播放的播放器Android邊下邊播播放器Android
- 邊學邊做的第一個Unity小遊戲Unity遊戲
- Kotlin邊用邊學:Inline Functions的適用場景KotlininlineFunction
- 小白也能操作Linux,十分鐘教你簡單的shell指令碼編寫邊學邊用Linux指令碼
- ASP.NET CORE 邊學邊記之 SwaggerUI簡單配置ASP.NETSwaggerUI
- SpringBoot邊學邊用(二)SpringBoot 整合 Mybatis(xml檔案形式)Spring BootMyBatisXML
- 【Python | 邊學邊敲邊記】第二次:深度&&廣度優先演算法Python演算法
- 視覺化學習:利用向量判斷多邊形邊界視覺化
- iOS邊下邊播總結iOS
- 寫網路爬蟲的法律邊界爬蟲
- 如何利用CSS寫一個六邊形?CSS
- 【從0到1學習邊緣容器系列1】之 邊緣計算與邊緣容器的起源
- 邊做邊學入門微信小程式之仿豆瓣評分微信小程式
- 在風變程式設計學習Python,找到了邊玩邊學的樂趣程式設計Python
- python去除圖片白邊黑邊Python
- 王炸!!IDEA 2021.1 推出語音、視訊功能,邊寫程式碼邊聊天,我真的服了…Idea
- Minecraft 從入門到入坑(邊玩遊戲邊學程式設計)Raft遊戲程式設計
- 風變程式設計邊學習邊實操,讓過程更快樂!程式設計
- unocss如何簡寫特定的邊角半徑CSS
- 邊聊邊複製,邊修改邊測試,利用chatgpt用laravel框架做一個部落格應用ChatGPTLaravel框架
- CSS 邊框陰影立體邊框CSS
- Unity 利用Cache實現邊下邊玩Unity
- 多邊形填充-活動邊表法
- [學習筆記] 邊學教程邊建“知識付費”應用 第1次總結筆記
- opencv學習之邊緣檢測OpenCV
- OctoberCMS 外掛學習 側邊欄
- Flutter實現一個邊讀邊處理邊傳送檔案的功能Flutter