This documentation is archived and is not being maintained.

Transferring an Established Session

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

Use methods of the SignalingSession class to refer a session participant to a remote participant in a Unified Communications Managed API version 1.0 SDK application on Microsoft Office Communications Server 2007.

Typically, a REFER message is used for transfer scenarios. If participants A and B are connected by an INVITE session, and A sends a REFER message to B referring to target participant C, then B accepts the request that would normally connect to C, and indicates the progress of the INVITE session using notifications to A. The REFER message creates an implicit subscription with B. When B sends a final notification, the subscription terminates. If B does not send a final NOTIFY, then the implicit subscription exists until the session is terminated. If a final notification is not received in a reasonable amount of time, the application can terminate the refer subscription by calling the TerminateSubscription method on the corresponding ReferStatus object passed to the Refer operation. The session will clean up any pending subscriptions.

Unified Communications Managed API version 1.0 exposes both asynchronous and synchronous versions of REFER functionality.

  • To refer synchronously, use the Refer method.
  • To refer asynchronously, use the BeginRefer and EndRefer methods.

It is recommended that applications not call the synchronous Refer method from any user interface (UI) thread, because this might block the thread. The Refer method is provided as a convenience for applications that call this method from a thread other than a UI thread. The following example demonstrates the use of the synchronous referral.

class ReferSample
{
  static void Main(string[] args)
  {
    ReferSample refer = new ReferSample();
    refer.ReferSynchronously();
  }

// Refer an URI synchronously.
  public void ReferSynchronously()
  {
    RealTimeServerConnectionManager connectionManager = new RealTimeServerTcpConnectionManager();
    SipPeerToPeerEndpoint endPoint = new SipPeerToPeerEndpoint("remote-sip-uri", connectionManager, SipTransportType.Tcp, "ProxyHostName", 5060);
    SignalingSession session = new SignalingSession(endPoint, new RealTimeAddress("sipURI"));
    ReferStatus referStatus = new ReferStatus();
    RealTimeAddress address = new RealTimeAddress("referred-uri");
    // Register a handler for the StateChanged event
    referStatus.StateChanged += new System.EventHandler<ReferStateChangedEventArgs>(refer_StateChanged);

    try
    {
      session.Refer(address, referStatus);
    }
    catch(RealTimeException ex)
    {
      Console.WriteLine("Refer failure for {0}: {1}", address.Uri, ex.ToString());
    }
  }

  // Handle the StateChanged event
  void refer_StateChanged(object sender, ReferStateChangedEventArgs e)
  {
    ReferStatus referStatus = (ReferStatus)sender;
    // Display the new Refer state value
    Console.WriteLine("status code is {0}, status text is {1}", RegistrationStateChangedEventArgs.NotifyStatusCode, RegistrationStateChangedEventArgs.NotifyStatusText);
  }
}

The following code example shows an asynchronous counterpart to the ReferSynchronously method in the previous example. A significant difference from the synchronous version is the presence of the Refer_Complete callback in the call to BeginRefer. After BeginRefer returns, Refer_Complete is called, which in turn calls EndRefer. As in the previous example, a handler is registered for the StateChanged event.

// Refer an URI asynchronously.
  public void ReferAsynchronously()
  {
    RealTimeServerConnectionManager connectionManager = (RealTimeServerConnectionManager)new RealTimeServerTcpConnectionManager();
    SipPeerToPeerEndpoint endPoint = new SipPeerToPeerEndpoint("sipURI", connectionManager, SipTransportType.Tcp, "domain name", 5060);
    SignalingSession session = new SignalingSession(endPoint, new RealTimeAddress("sipURI"));
    ReferStatus referStatus = new ReferStatus();
    RealTimeAddress address = new RealTimeAddress("sessionTargetURI");
    referStatus.StateChanged += new System.EventHandler<ReferStateChangedEventArgs>(refer_StateChanged);

    try
    {
      session.BeginRefer(address, referStatus, this.OnReferCompleted, session);
    }
    catch (InvalidOperationException ex)
    {
      Console.WriteLine("Invalid operation exception in Refer failure for {0}: {1}", address.ToString(), ex.ToString());
    }

    catch (RealTimeException ex)
    {
      Console.WriteLine("Refer failure for {0}: {1}", address.ToString(), ex.ToString());
    }
  }

  void OnReferCompleted(IAsyncResult asyncResult)
  {
    SignalingSession session = asyncResult.AsyncState as SignalingSession;
    try
    { 
      session.EndRefer(asyncResult);
    }
    catch (RealTimeException ex)
    {
      Console.WriteLine("Refer failure for {0}: {1}", asyncResult.ToString(), ex.ToString());
    }
  }

  // Handle the StateChanged event
  void refer_StateChanged(object sender, ReferStateChangedEventArgs e)
  {
    ReferStatus referStatus = (ReferStatus)sender;
    // Display the new Refer state value
    Console.WriteLine("Refer state is {0}", referStatus.State);
  }
}
Show: