libjingle翻译之《Important Concepts(重要概念)之Signals (信号)》

来源:互联网 发布:java如何编译成class 编辑:程序博客网 时间:2024/05/16 07:44

Important Concepts(重要概念)

你应该理解libjingle中以下的重要概念:

● Signals                                          (信号)

● Threads and Messages                     (线程、消息)

● Naming Conventions                        (命名约定)

● SSL Support                                    SSL 支持)

● Connections                                    (链接)

● Transports, Channels, and Connections (传输、通道、链接)

● Candidates                                     (协商)

● Data Packets                                   (数据包)

 

 

Signals   (信号)

libjingle 使用sigslot库 促进对象间的通信。sigslot是一种framework,它可以把呼叫方(calling member)和任意类实现的接收函数很容易地关联起来,工作方式就像这样:

1、  发出呼叫的类声明一个数据成员(被称作信号),声明方式使用一种很像模板的语法。这个信号数据成员定义了和接收函数一致的参数。(注:这个接收函数当然是属于某个类了)

2、  类中的接收函数在实现时,它的参数必须与它关联的信号的参数相同,这里的参数相同是指数量相同,类型相同和次序相同。这个接收函数有时被称作receiver或slot(注意:接收函数可以与信号数据成员同属一个类)。接收函数不能有返回值(可以是void)。它必须继承自sigslot::has_slots<>。

3、  通过呼叫信号数据成员的connect函数,使信号数据成员与接收函数关联起来,呼叫时传递两个参数:一个是接收函数所在类的对象指针,另一个是类中的接收函数的地址。

4、  呼叫方使用信号成员就像是调用它自己的函数一样,传递给与信号成员声明时一致的参数就可以了。如果调用信号成员成功,则所有与此信号成员关联的任意类中的接收函数都会被调用。

我们可以把任意数量的信号成员与一个接收函数关系起来。libjingle有时就是把多个信号成员与一个接收函数关联起来,达到统一处理消息之目的。相反,一些类对象声明一个信号对象,是为了从一个“信号点”广播消息(“信号点”语意上讲就是一个信号成员对象,此对象关联了众多的接收函数,当此信号成员被调用时,这些接收函数都能接收到消息,即这些接收函数都被调用)。当对象(包括信号成员所在对象和传递给connect函数的接收函数所属类对象)被销毁时,sigslot库会小心处理取消关联和引用关系。

下面的代码示范了sigslot库的使用方法:

 

// Class that sends the notification.

class Sender {

// The signal declaration.

// The &apos;2&apos; 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&apos;t return a value.

void Receiver::OnDanger(string message, std::time_t time){

if(message == "Help!")

{

// Call the police

...

}

}

...

}

 

Sender 类声明了一个信号数据成员:

sigslot::signal2<string message, std::time_t time> SignalDanger;

       语句中的“<string message, std::time_t time>”声明了可以与此信号成员关联的接收函数的参数形式,必须是 void functionName( string,std::time_t )形式。

       从Sender类的成员数void Panic()实现中可以看到,使用信号成员的形式就像是在调用一个与信号成员同名的函数SignalDanger("Help!", std::time(0));,参数类型就是声明信号成员时指定的参数。

 

Receiver类继承自sigslot::has_slots<>,它的成员函数就具有了成为“接收函数”的“潜质”。

       从Receiver的构造函数可以看出,当Receiver对象创建时,必须向它指定一个信号类(即声明了信号成员的类)对象作为构建造函数的参数,当然此信号类必须有Receiver定义的操作用到的信号成员的样式。

       一旦Receiver类对象被创建,Sender类中的信号成员就与Receiver类中的OnDanger()函数关联起来了,只要Sender对象的Panic()被调用,Receiver类对象的OnDanger()就被调用,即接收到来自Sender对象的消息,从而进行处理。

:

 

Sender sender;

Receiver  receiver(sender);

如果 运行:

sender.Panic();

receiver.OnDanger();

被自动调用,在此函数的内部就可以处理来自sender的消息。

实现了信号类与接收类之间的松偶合性。

 

libjingle库中的一些类,发送信号给接收函数(即listeners 监听者,可理解为某个类的接收函数),用来传递一些重要事件。比如:当你发出或收到一个链接尝试时,Call::SignalSessionState就会发出通知信号。在应用程序中应该有接收函数与这些信号关联起来,并且做出适当的行为。

 

按照libjingle中的约定,在声明信号数据成员时,名字被冠以“Signal”字符,比如:SignalStateChange,SignalSessionState,SignalSessionCreate。

与这些信号关联的函数名被冠以“On”,比如:OnPortDestropyed(),OnOutgoingMessage(),OnSendPacket();

 

关于 sigslot库的更多内容,请查看sigslot文档。

 

若有错误,请您指正,thanks!

原创粉丝点击