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.

Synchronous Transfers

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.

Copy Code
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);
  }
}

Asynchronous Transfers

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.

Copy Code
// 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);
  }
}

See Also