# 基于reSIProcate的SIP协议栈研究--DUM和SIPStack的多线程运行

> In the latest work session we've done some refactoring of resiprocate
> to support having multiple Transaction Users (TU) in a resip-based
> application. There are a few implications and interface changes.
>
> - DialogUsageManager constructor now must take a SipStack&
> - UserProfile::setDigestCredential no longer takes an aor argument
> since the UserProfile is already bound to an aor
> - Applications can have multiple TransactionUsers (e.g.
> DialogUsageManager or Proxy). Each TU needs to register with the
> TransactionUserSelector using this interface
> SipStack::registerTransactionUser(TransactionUser& tu). The
> DialogUsageManager will do this for you in its constructor.
>
> Keep in mind that this means your application needs to make a SipStack
> and pass it into the DialogUsageManager. If you are creating multiple
> TUs you should share the same SipStack with each of these.
>
> Each incoming message is  matched against the list of TUs that have
> been registered with the SipStack.  More to follow on this topic.

//DialogUsageManager 和 SipStack 运行在各自独立线程，和程序主线程独立
> As a convenience, there are two classes which help you run your
> DialogUsageManager and/or SipStack in their own threads. For example,
> if you were writing a presence server or registrar, you could use the
> following approach:

 SipStack stack; StackThread stackThread(stack); DialogUsageManager dum(stack); DumThread dumThread(dum);   stackThread.run(); dumThread.run(); stackThread.join(); dumThread.join();

//DialogUsageManager和程序主线程一起，SipStack运行于独立的线程
> If you are implementing a useragent such as a softphone that might
> have a gui component running the same thread as the dum, use this

 SipStack stack;  StackThread stackThread(stack);    DialogUsageManager dum(stack);  stackThread.run();    while (!shutdown) // some local variable  {      while (dum.process());      // do your gui stuff here.  }  stackThread.join();

//DialogUsageManager和SipStack都运行在程序主线程同一线程中
> You can also run without a StackThread if you'd like everything to run

 SipStack stack;  DialogUsageManager dum(stack);  while (!shutdown) // some local variable  {        try        {           resip::FdSet fdset;           buildFdSet(fdset);           stack.buildFdSet(fdset);           int ret = fdset.selectMilliSeconds(stack.getTimeTillNextProcessMS());           if (ret >= 0)           {              stack.process(fdset);           }        }        catch (BaseException& e)        {           InfoLog (<< "Unhandled exception: " << e);        }        while (dum.process());      // do your gui stuff here.  }

> There will be more to follow on how to use the new Proxy TU - as well

> as how to use the Proxy TU in conjunction with one or more User Agent
> TUs.

Here is the explaination of some lines of code above:

buildFdSet - iterates through all of the stacks socket read/write handles
and builds a list to pass to the select function.

selectMilliSeconds - Waits for one of the handles returned from buildFdSet
to be signaled (ie. inbound SIP message) - waits for a specified number of
milliseconds.

getTimeTillNextProcessMs() - iterates through all timers to see when the
next time that the stack will need to do work to service timers

process - iterates through all transports FIFOs and timers and processes
inbound and/or SIP messages and timer expirations.  ie.  Does all of the
work!