1.客戶端連接服務器,並發送消息給服務器的處理在ejabberd_c2s中。
ejabberd_c2s 是一個gen_fsm 狀態機,在 ejabberd啟動時裝載。
初始狀態為 wait_for_stream,接受形為 {xmlstreamstart, _Name, Attrs} 的消息,其他任何消息都會導致stop。
接受到連接請求,發送feature 請求后狀態改為wait_for_feature_request 。
接受到feature 再發送challenge 后,狀態改為 wait_for_sasl_response。
經過sasl鑒權后,狀態改為 wait_for_stream, 此時 StateData#state.authenticated 已經不為false。
客戶端重新發起<stream> 連接請求,服務器發送bind 消息,狀態改為 wait_for_bind 。
客戶端發送bind 與資源綁定,服務器按照策略驗證是否允許相同的用戶用不同的資源連接,通過后狀態改為 wait_for_session。
客戶端發送<iq> 消息創建session,服務器調用 ejabberd_sm:open_session 后將狀態改為 session_established。
客戶端發送普通的通信消息<iq>,<presence>,<message> 等,都通過session_established2/2 函數處理。
2.下面是比較關鍵的ejabberd中函數調用的分析:
Ls變量實際上是一個包含多個要具體調用的函數定義的列表,列表里面的元組分為兩類:[{_Seq, Node,Moudle,Function} | Ls2] [{_Seq,Module,Function} | Ls2],
run_fold1/4 的作用就是使用Args參數依次調用這個Ls列表里的方法.
run_fold1/4 最終會返回調用的結果出來.
所以從最終結果來看 ejabberd_hooks:run_fold/4 方法就是去表hooks查找並調用所需的函數返回調用結果.
針對上面的代碼就是: 使用{c2s_update_presence,Server}作為key 在表hooks 中查找 要調用的方法列表,並使用[User,Server] 作為參數進行調用.
這個key具體找到什么樣的方法呢? 我們可以在源碼中查找下:
查找結果中可以看到
mod_vcard_xupdate.erl ejabberd_hooks:add(c2s_update_presence, Host
我們在mod_vcard_xupdate.erl中找到這段代碼:
update_presence就所我們所要找的方法了.