reSIProcate学习笔记(五)


TransactionMessage、TransactionUser

继承关系:SipMessage => TransactionMessage => Message

先来看看这个消息传递的基类 —— Message类的保护数据成员为TransactionUser* mTu; 内部有一个嵌套类:

class Brief
{
public:
    Brief(const Message& src);
    const Message& mSource;
};

Message类的纯虚函数virtual Message* clone() const = 0; 在TransactionMessage类中实现:

virtual Message* clone() const { resip_assert(false); return NULL; }

上面的此外resip_assert宏就是assert宏,TransactionMessage类还新增了两个纯虚函数:

virtual const Data& getTransactionId() const = 0;
// indicates this message is associated with a Client Transaction for the purpose of determining which TransactionMap to use
virtual bool isClientTransaction() const = 0;

SipMessage是核心类,较为复杂,每个SipMessage都需要由TuSelector类决定发送给哪个TransactionUser,先分析TransactionUser类,此类隶属于app-layer,先将类注释抄摘如下:

/* Subclasses of TransactionUser are expected to do the following things:
– Register itself by using SipStack::registerTransactionUser().
– Regularly pull messages out of mFifo, and process them.
– Particularly, every received SIP request MUST be responded to, or the stack will leak transactions.
– Before the TransactionUser is destroyed, it should ensure that it has been unregistered from the stack using SipStack::unregisterTransactionUser(), and gotten a confirmation in the form of a TransactionUserMessage.

There is also a collection of things you can do to customize how the stack interacts with your TransactionUser:
– If you wish to restrict the types of SIP traffic your TransactionUser will receive from the stack, you can do so by setting the MessageFilterRuleList, either in the constructor, or with setMessageFilterRuleList() (see MessageFilterRule for more)
– If you need more fine-grained control over what SIP messages your TransactionUser is willing/able to handle, you can override TransactionUser::isForMe().
– If you wish your TransactionUser to be notified whenever a transaction ends, just pass RegisterForTransactionTermination in the constructor.
– If you wish your TransactionUser to be notified when Connections are closed, pass RegisterForConnectionTermination in the constructor. */

TransactionUser负责从mFifo中取出Message并处理,其数据成员有:

/* @brief  This TransactionUser’s fifo. All communication with the TransactionUser goes through here. */
TimeLimitFifo<Message> mFifo;
CongestionManager* mCongestionManager;
MessageFilterRuleList mRuleList;
typedef std::set<Data> DomainList;
DomainList mDomainList;
bool mRegisteredForTransactionTermination;
bool mRegisteredForConnectionTermination;
bool mRegisteredForKeepAlivePongs;

下面的API用来过滤TransactionUser接收到的Message

/* @brief  Sets this TransactionUser’s MessageFilterRuleList.
This tells the stack which SIP messages this TransactionUser is interested in, and which ones it is not. This allows multiple TransactionUsers to run on top of the same SipStack. @param  rules The MessageFilterRuleList to use. */
void setMessageFilterRuleList(MessageFilterRuleList &rules);

下面的三个枚举类型就是三个bool数据成员的取值范围:

enum TransactionTermination 
{
    RegisterForTransactionTermination,
    DoNotRegisterForTransactionTermination
};
enum ConnectionTermination 
{
    RegisterForConnectionTermination,
    DoNotRegisterForConnectionTermination
};
enum KeepAlivePongs
{
    RegisterForKeepAlivePongs,
    DoNotRegisterForKeepAlivePongs
};

构造函数的默认取值都是不通知:

/* @brief Constructor that specifies the MessageFilterRuleList, whether this TransactionUser needs to hear about the completion of  transactions, and the closing of connections.
   @param rules The MessageFilterRuleList to use. (A copy is made)
   @param t Whether or not the TransactionUser should be informed when transactions end (disabled by default).
   @param c Whether or not the TransactionUser should be informed when connections close (disabled by default).
   @note This is protected to ensure than no-one constructs the base-class. (Subclasses call this in their constructor) */
TransactionUser(MessageFilterRuleList &rules, TransactionTermination t = DoNotRegisterForTransactionTermination, ConnectionTermination c = DoNotRegisterForConnectionTermination, KeepAlivePongs k = DoNotRegisterForKeepAlivePongs);

函数post()用来把Message提交到fifo中去:

/* @brief Posts a Message to this TransactionUser’s fifo. Ownership of msg is taken.
@param msg The Message to add to mFifo. (This takes ownership of msg) */
void post(Message* msg) { mFifo.add(msg, TimeLimitFifo<Message>::InternalElement); }

/*@brief Returns true iff domain matches one of the domains that this TransactionUser is responsible for. (added with addDomain). */
bool TransactionUser::isMyDomain(const Data& domain) const
{ // Domain search should be case insensitive – search in lowercase only
return mDomainList.count(Data(domain).lowercase()) > 0;
}
/* @brief Adds a domain to the set of domains that this TransactionUser is responsible for. */
void TransactionUser::addDomain(const Data& domain)
{ // Domain search should be case insensitive – store in lowercase only
mDomainList.insert(Data(domain).lowercase());
}

分析完TransactionUser,来看看TransactionUserMessage,它是TransactionMessage的共有派生类。

枚举成员Type是针对TransactionUser的操作,唯一的数据成员就是Type型:

typedef enum 
{
    RequestShutdown,
    RemoveTransactionUser,
    TransactionUserRemoved
} Type;

Type mType;

显然,构造函数的形参应当包括Type和TransactionUser:

TransactionUserMessage(Type type, TransactionUser* tu);

TransactionMessage此外还有一个派生类名为TransactionTerminated,构造函数和数据成员如下:

TransactionTerminated(const Data& tid, bool isClient, TransactionUser* ptu) : mTransactionId(tid), mIsClient(isClient)
{
    setTransactionUser(ptu);         
}

Data mTransactionId;
bool mIsClient;

布尔值mIsClient用来区别是Client还是Server的状态是Terminated。

TransactionMessage是通过TuSelector类和TransactionUser联系起来的,现在来看看这个桥梁。

TuSelector类的数据成员较多,罗列如下:

struct Item
{
    Item(TransactionUser* ptu) : tu(ptu), shuttingDown(false) {}
    TransactionUser* tu;
    bool shuttingDown;
    bool operator==(const Item& rhs) { return tu == rhs.tu; }
};
typedef std::vector<Item> TuList;
TuList mTuList;
TimeLimitFifo<Message>& mFallBackFifo;
CongestionManager* mCongestionManager;
AsyncProcessHandler *mFallbackPostNotify;
Fifo<TransactionUserMessage> mShutdownFifo;
bool mTuSelectorMode;
StatisticsMessage::Payload mStatsPayload;

每个Item对应一个TransactionUser,而且还包含了这个TransactionUser是否已经关闭的布尔值,mTuList是这一系列Item的存储向量,再来看看其构造函数:

TuSelector::TuSelector(TimeLimitFifo<Message>& fallBackFifo) :
    mFallBackFifo(fallBackFifo), 
    mCongestionManager(0),
    mFallbackPostNotify(0),
    mTuSelectorMode(false),
    mStatsPayload()
{
    mShutdownFifo.setDescription("TuSelector::mShutdownFifo");
}

process()函数用来处理TransactionUserMessage消息:

void TuSelector::process()
{
    if (mShutdownFifo.messageAvailable())
    {
        TransactionUserMessage* msg = mShutdownFifo.getNext();  
        switch (msg->type())
        {
            case TransactionUserMessage::RequestShutdown:
                InfoLog (<< "TransactionUserMessage::RequestShutdown " << *(msg->getTransactionUser()));
                markShuttingDown(msg->getTransactionUser());
                break;
            case TransactionUserMessage::RemoveTransactionUser:
                InfoLog (<< "TransactionUserMessage::RemoveTransactionUser " << *(msg->getTransactionUser()));
                remove(msg->getTransactionUser());
                break;
            default:
                resip_assert(0);
                break;
        }
        delete msg;
    }
}

未完待续..

Leave a comment

邮箱地址不会被公开。 必填项已用*标注