Mosquitto-1.5.4原始碼分析,PUBLISH的實現及函式跳轉關係
阿新 • • 發佈:2018-12-12
客戶端向伺服器傳送資料包(packet)時,首先將資料包放到改傳送佇列中,並不真實發送資料,而是傳送資料就緒訊號,等待loop事件迴圈呼叫的函式db__message_write根據網路連線情況來處理髮送請求;該佇列為單鏈表儲存結構,每次有新資料包需要傳送時,將新資料包插入到連結串列尾部;真正傳送資料時從連結串列頭部開始傳送資料包。
階段1、準備好需要傳送的資料包,參見截圖1的上半部分的單步斷點處,非常關鍵,inflight_msgs就是在此處賦值的。
截圖1的下半部分,每一個函式的跳轉關係一目瞭然。
截圖1
階段2、在loop.c的事件迴圈裡面,一直在呼叫函式db__message_write,通過它實現真正的傳送,
/* Local bridges never time out in this fashion. */
if(!(context->keepalive)
|| context->bridge
|| now - context->last_msg_in <= (time_t)(context->keepalive)*3/2){
if(db__message_write(db, context) == MOSQ_ERR_SUCCESS){ //firecat,real_send_publish
該函式體在database.c定義,它反覆在判斷inflight_msgs是否為空。不為空表示有待發送的資料包。
截圖2
個人建議:
在單步除錯,檢視業務主題訊息流程時,建議把系統主題的訊息遮蔽掉。方法如下:
1、/src/mosquitto.c,第294行,程式碼註釋掉
#ifdef WITH_SYS_TREE
//sys_tree__init(&int_db);//firecat,SYS,"$SYS/broker/#"
#endif
2、/src/loop.c,第204行,程式碼註釋掉
if(db->config->sys_interval > 0){
//sys_tree__update(db, db->config->sys_interval, start_time);//firecat,SYS,"$SYS/broker/#"
}
或者乾脆一點,在CMakeLists直接把巨集WITH_SYS_TREE設定成未定義。