1. 程式人生 > >Mosquitto-1.5.4原始碼分析,PUBLISH的實現及函式跳轉關係

Mosquitto-1.5.4原始碼分析,PUBLISH的實現及函式跳轉關係

客戶端向伺服器傳送資料包(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設定成未定義。