8 Khala的裝置間管理 通訊

2022-08-16 04:06:14 字數 3308 閱讀 2073

在之前的文件中,我們都是從單個裝置的角度進行介紹,但在實際業務中,不同裝置間存在互動行為。我們經常需要在乙個裝置的生命週期中查詢另乙個裝置資訊,或者向另乙個裝置進行通訊。因此我們提供了裝置管理模組來對不同裝置進行查詢與通訊等互動管理。

目前裝置管理模組提供了如下介面:

bool hasnode(uint id);

查詢某個id的裝置是否已經登入。

bool find(uint id, infonodeptr& infonodeptr);

查詢某個id的裝置節點物件資訊,我們可以通過infonodeptr節點物件查詢具體節點裝置的資訊,或者通過infonodeptr.send()介面向該裝置物件傳送訊息。

std::vectorgetnodeids(objecttype* objecttype);

查詢符合該型別的所有已登入的裝置節點id,只查詢該型別,不支援該型別的派生型別的查詢。

std::vectorgetnodeids(const std::string& type);

查詢符合該型別的所有已登入的裝置節點id,只查詢該型別,不支援該型別的派生型別的查詢。

template

std::vectorgetallnodeids(type objecttype);

查詢符合該型別,或者為該型別的派生型別的所有已登入的裝置節點id,比如燈節點型別lighttype,派生了日光燈daylighttype型別,呼叫getallnodeids(lighttype)將會獲得所有直接為燈節點型別的id,和派生於燈節點,如日光燈型別的id。

template

std::vectorgetallnodeids(type* objecttype);

查詢符合該型別,或者為該型別的派生型別的所有已登入的裝置節點id,傳入型別為該型別的指標。

getallnodeids()介面中,引數為objecttype的派生型別物件或指標,實際只需獲得具體的物件型別。因為c++的rtti機制並不能實現:已知兩個物件,判斷這兩個物件是否存在派生關係。而只能實現已知乙個物件和乙個具體型別,判斷這個物件是否派生於這個具體型別(通過dynamic_cast判斷指標是否為空)。當然也可以通過反射和rtti機制實現獲取物件的具體型別,但是c++也不支援反射/(ㄒoㄒ)/~~。因此該介面的實現採用泛型的形式,必須通過引數傳入具體的型別。所以我嘗試實現很久的引數為字串型別的std::vectorgetallnodeids(const std::string& type)介面只能胎死腹中。當然rtti肯定效率感人,但目前本學渣只會這種實現了/(ㄒoㄒ)/~~。

我們通過建立乙個mymanagetype的裝置型別來測試以上介面。在objecttype的派生類中,我們通過this->getnodemanager()介面即可獲得裝置管理模組,並使用以上介面。

在mymanagetype型別中,我們實現ongetidbytype的訊息事件,通過測試getnodeids來獲取所有同型別的裝置id,具體實現如下:

bool mymanagetype::ongetidbytype(khala::infonodeptr&infonodeptr,

json::value&msg, khala::timestamp time)

infonodeptr->send(ss.str());

return

true

;}

我們通過客戶端進行測試(./example/testclient/hellokhalaclient4.py)。我們開啟兩個客戶端,進行login操作,並在其中乙個客戶端測試idbytype訊息事件。

此時顯示存在兩個裝置型別為my_manage_type的裝置,id分別為(懶得抄)…

我們實現ongetallidbyobject的訊息事件,通過測試getallnodeids來獲取所有派生於該型別的裝置的id,具體實現如下:

bool mymanagetype::ongetallidbyobject(khala::infonodeptr&infonodeptr,

json::value&msg, khala::timestamp time)

infonodeptr->send(ss.str());

//記得delete

delete

tmp;

return

true

;}

同樣我們在其中乙個客戶端測試aidbyobject訊息事件。

因為我們查詢的是nodetype型別,而我們建立的mymanagetype型別繼承於nodetype型別,因此依舊會顯示這兩個my_manage_type型別的id。

我們實現asklogin的訊息事件,不同於系統預設的islogin訊息事件,asklogin通過測試hasnode來判斷任意指定的id裝置是否登入。

bool mymanagetype::onasklogin(khala::infonodeptr& infonodeptr, json::value&msg,

khala::timestamp time)

else

infonodeptr->send(ss.str());

return

true

;}

同樣我們在其中乙個客戶端測試asklogin訊息事件。

我們自身的id為2075756572,因此我們查詢另乙個客戶端的id:313508835,此時顯示該id已經登入。

最後我們實現sendmsg訊息事件,通過測試find介面,並傳送訊息進行通訊。

bool mymanagetype::onsendtonode(khala::infonodeptr&infonodeptr,

json::value&msg, khala::timestamp time)

return

true

;}

偷個小懶,自己給自己發訊息,通過客戶端進行測試。

接收訊息成功。實際不同裝置間進行通訊,只需傳入實際裝置的id,在根據id呼叫find()介面,最後通過獲取的infonodeptr呼叫send()即可,不同裝置間進行通訊就這麼簡單。

iOS 裝置與其配件間的通訊

與擴充套件配件通訊,需要你同配件廠商通力合作,並理解其配件所提供的服務。而廠商必須精準的支援其硬體裝置同ios之間的通訊。作為支援的一部分,其配件必須支援至少一種命令列協議,該協議用於配件與其相配套的應用之間進行資料的傳輸,並且廠家可以自定義該協議,或者使用其他廠商支援的標準協議,而蘋果公司並不註冊...

程序間通訊的8種方式

無名管道 pipe 管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。高階管道 popen 將另乙個程式當做乙個新的程序在當前程式程序中啟動,則它算是當前程式的子程序,這種方式我們成為高階管道方式。有名管道 named pipe 有...

程序間通訊的8種方式

前言 程序通訊 每個程序各自有不同的使用者位址空間,任何乙個程序的全域性變數在另乙個程序中都看不到,所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,程序a把資料從使用者空間拷到核心緩衝區,程序b再從核心緩衝區把資料讀走,核心提供的這種機制稱為程序間通訊。程序間通訊 ipc 介紹 程序間通...