我注意到發送到gen_fsm進程的pid的消息在狀態回調中與事件匹配。這是偶然還是我可以依靠這個功能?我可以在gen_fsm狀態回調中處理任何收到的消息嗎?
正常情況下,我希望發送到gen_fsm的常規消息顯示在handle_info/3回調中,並且認爲我必須使用gen_fsm:send_event重新發送消息。
gen_fsm是否嘗試首先將消息與狀態回調匹配,然後用handle_info/3回調進行通信?或者僅當它與狀態回調子句不匹配?
但是,當我嘗試它時,我的消息似乎根據調試輸出處理兩次。
所以基本上這個問題也可以這樣說:如何正確處理接收到的消息作爲gen_fsm狀態函數中的事件?
澄清:,一些事件被獲取傳遞應考慮對這個問題給出的消息出現。
我知道,在很多情況下,它的清潔程度只能通過函數調用進入fsm來使協議可見。
我不太確定這是否會改善上述gen_fsm必須適用的當前框架:每個層調用connect()函數來附加(有時啓動)較低層的各種協議棧。數據包被髮送到較低層,調用一個函數(發送)並由receive
收到一條消息。很像gen_tcp。
通過查看gen_fsm的代碼,我已經知道一般消息只傳遞給handle_info,因此只有使用gen_fsm:send_event直接從handle_info/3回調或resent調用狀態函數的問題仍然存在。
我在這裏是否正確理解了你,你是否僅僅將gen_fsm用於某些協議棧而不是全部?如果是這樣,爲什麼?爲什麼不以同樣的方式實現堆棧的所有Erlang部分?這將使您在發送和接收郵件方面保持一致。 – rvirding 2010-10-19 12:52:49
我一直在抱怨{ok,Pid} = connect(),發送(Pid,Data)和接收{resp,Data}消息。所以我在堆棧中不同模塊的API中保持一致。我不一致的地方是目前接收和發送的處理。 – 2010-10-20 09:58:11
但是有很多使用這種範式的先前代碼,所以它試圖改變一切。對堆棧的所有部分不使用gen_fsm的原因是其實際上非常不同的協議(汽車總線協議)通過USB多路複用。所以堆棧的各個部分在gen_server,簡單ad/hoc服務器和無狀態編碼/解碼過濾器以及gen_fsm當然不同。 – 2010-10-20 10:05:03