Important Concepts(重要概念)
你應該理解libjingle中以下的重要概念:
● Signals (信號)
● Threads and Messages (線程、消息)
● Naming Conventions (命名約定)
● SSL Support (SSL 支持)
● Connections (鏈接)
● Transports, Channels, and Connections (傳輸、通道、鏈接)
● Candidates (協(xié)商)
● Data Packets (數(shù)據(jù)包)
Signals (信號)
libjingle 使用sigslot庫 促進對象間的通信。sigslot是一種framework,它可以把呼叫方(calling member)和任意類實現(xiàn)的接收函數(shù)很容易地關(guān)聯(lián)起來,工作方式就像這樣:
1、 發(fā)出呼叫的類聲明一個數(shù)據(jù)成員(被稱作信號),聲明方式使用一種很像模板的語法。這個信號數(shù)據(jù)成員定義了和接收函數(shù)一致的參數(shù)。(注:這個接收函數(shù)當然是屬于某個類了)
2、 類中的接收函數(shù)在實現(xiàn)時,它的參數(shù)必須與它關(guān)聯(lián)的信號的參數(shù)相同,這里的參數(shù)相同是指數(shù)量相同,類型相同和次序相同。這個接收函數(shù)有時被稱作receiver或slot(注意:接收函數(shù)可以與信號數(shù)據(jù)成員同屬一個類)。接收函數(shù)不能有返回值(可以是void)。它必須繼承自sigslot::has_slots<>。
3、 通過呼叫信號數(shù)據(jù)成員的connect函數(shù),使信號數(shù)據(jù)成員與接收函數(shù)關(guān)聯(lián)起來,呼叫時傳遞兩個參數(shù):一個是接收函數(shù)所在類的對象指針,另一個是類中的接收函數(shù)的地址。
4、 呼叫方使用信號成員就像是調(diào)用它自己的函數(shù)一樣,傳遞給與信號成員聲明時一致的參數(shù)就可以了。如果調(diào)用信號成員成功,則所有與此信號成員關(guān)聯(lián)的任意類中的接收函數(shù)都會被調(diào)用。
我們可以把任意數(shù)量的信號成員與一個接收函數(shù)關(guān)系起來。libjingle有時就是把多個信號成員與一個接收函數(shù)關(guān)聯(lián)起來,達到統(tǒng)一處理消息之目的。相反,一些類對象聲明一個信號對象,是為了從一個“信號點”廣播消息(“信號點”語意上講就是一個信號成員對象,此對象關(guān)聯(lián)了眾多的接收函數(shù),當此信號成員被調(diào)用時,這些接收函數(shù)都能接收到消息,即這些接收函數(shù)都被調(diào)用)。當對象(包括信號成員所在對象和傳遞給connect函數(shù)的接收函數(shù)所屬類對象)被銷毀時,sigslot庫會小心處理取消關(guān)聯(lián)和引用關(guān)系。
下面的代碼示范了sigslot庫的使用方法:
// Class that sends the notification.
class Sender {
// The signal declaration.
// The '2' in the name indicates the number of parameters. Parameter //types
// are declared in the template parameter list.
sigslot::signal2<string message, std::time_t time> SignalDanger;
// When anyone calls Panic(), we will send the SignalDanger signal.
void Panic(){
SignalDanger("Help!", std::time(0));
}
// Listening class. It must inherit sigslot.
class Receiver : public sigslot::has_slots<>{
// Receiver registers to get SignalDanger signals.
// When SignalDanger is sent, it is caught by OnDanger().
// Second parameter gives address of the listener function class definition.
// First parameter points to instance of this class to receive notifications.
Receiver(Sender sender){
sender->SignalDanger.connect(this, &Receiver.OnDanger);
}
// When anyone calls Panic(), Receiver::OnDanger gets the message.
// Notice that the number and type of parameters match
// those in Sender::SignalDanger, and that it doesn't return a value.
void Receiver::OnDanger(string message, std::time_t time){
if(message == "Help!")
{
// Call the police
...
}
}
...
}
Sender 類聲明了一個信號數(shù)據(jù)成員:
sigslot::signal2<string message, std::time_t time> SignalDanger;
語句中的“<string message, std::time_t time>”聲明了可以與此信號成員關(guān)聯(lián)的接收函數(shù)的參數(shù)形式,必須是 void functionName( string,std::time_t )形式。
從Sender類的成員數(shù)void Panic()實現(xiàn)中可以看到,使用信號成員的形式就像是在調(diào)用一個與信號成員同名的函數(shù)SignalDanger("Help!", std::time(0));,參數(shù)類型就是聲明信號成員時指定的參數(shù)。
Receiver類繼承自sigslot::has_slots<>,它的成員函數(shù)就具有了成為“接收函數(shù)”的“潛質(zhì)”。
從Receiver的構(gòu)造函數(shù)可以看出,當Receiver對象創(chuàng)建時,必須向它指定一個信號類(即聲明了信號成員的類)對象作為構(gòu)建造函數(shù)的參數(shù),當然此信號類必須有Receiver定義的操作用到的信號成員的樣式。
一旦Receiver類對象被創(chuàng)建,Sender類中的信號成員就與Receiver類中的OnDanger()函數(shù)關(guān)聯(lián)起來了,只要Sender對象的Panic()被調(diào)用,Receiver類對象的OnDanger()就被調(diào)用,即接收到來自Sender對象的消息,從而進行處理。
如:
Sender sender;
Receiver receiver(sender);
如果 運行:
sender.Panic();
則
receiver.OnDanger();
被自動調(diào)用,在此函數(shù)的內(nèi)部就可以處理來自sender的消息。
實現(xiàn)了信號類與接收類之間的松偶合性。
libjingle庫中的一些類,發(fā)送信號給接收函數(shù)(即listeners 監(jiān)聽者,可理解為某個類的接收函數(shù)),用來傳遞一些重要事件。比如:當你發(fā)出或收到一個鏈接嘗試時,Call::SignalSessionState就會發(fā)出通知信號。在應用程序中應該有接收函數(shù)與這些信號關(guān)聯(lián)起來,并且做出適當?shù)男袨椤?/span>
按照libjingle中的約定,在聲明信號數(shù)據(jù)成員時,名字被冠以“Signal”字符,比如:SignalStateChange,SignalSessionState,SignalSessionCreate。
與這些信號關(guān)聯(lián)的函數(shù)名被冠以“On”,比如:OnPortDestropyed(),OnOutgoingMessage(),OnSendPacket();
關(guān)于 sigslot庫的更多內(nèi)容,請查看sigslot文檔。
若有錯誤,請您指正,thanks!