Use the IOfferAnswer interface in the Unified Communications Managed API version 1.0 SDK to broadcast a text message to the members of a Microsoft Active Directory directory service Domain Services distribution group. This walkthrough constructs a simple version of the BroadcastIM sample application. For more information, see Broadcast IM Sample Application.

To allow the user to focus on the basics of using the IOfferAnswer interface to send a text message, the following features of the IMBroadcast sample are not included in this walkthrough:

Prerequisites

Open a New Project

Create a new Microsoft Windows Visual C# application.

To create the Unified Communications Managed API version 1.0 project

  1. Open a new Visual C# project in Microsoft Visual Studio 2005. Select Windows Application as the project type. Name the project BroadcastIM.

  2. Add a reference to Microsoft.Rtc.Collaboration.dll, which is installed at %ProgramFiles%\Office Communications Server 2007\UCMA v1.0 SDK.

  3. Add a class and a second Windows Form to the project. Name the class file BroadcastIM.cs.

  4. In the Toolbox, click Components to display components available to add to Visual C# designers.

  5. Drag and drop a BackgroundWorker component onto the design surface for Form2. In the Properties Window, set the WorkerReportsProgress and WorkerSupportsCancellation properties to True.

  6. Add controls to Form1 and Form2. Use the property settings specified in the following tables.

    Form1 Controls Property Property Value

    textBox

    Name

    textBoxDomainName

    Label

    Text

    Domain Name

    textBox

    Name

    textBoxSipUri

    Label

    Text

    SIP URI

    Button

    Name

    buttonSet

    Button

    Text

    Set

    Button

    Name

    buttonNew

    Button

    Text

    New

    Form2 Controls Property Property Value

    textBox

    Name

    textBoxMessage

    Label

    Text

    Message

    textBox

    Name

    textBoxDestination

    Label

    Text

    Destination

    Button

    Name

    buttonSend

    Button

    Text

    Send

  7. Use the following procedures to add code to Form1, Form2, and BroadcastIM.cs.

Add Code

Add code to the three files.

To add code to Form1

  1. Add the following using statement to Form1.

    Copy Code
    using Microsoft.Rtc.Signaling;
    
  2. Add the following declarations above the Form1 constructor.

    Copy Code
    internal SipPeerToPeerEndpoint m_SipPeerToPeerEndpoint;
    RealTimeServerConnectionManager m_RealTimeServerConnectionManager;
    
  3. Double-click the Set button and then add the following code to the button's event handler.

    Copy Code
    m_RealTimeServerConnectionManager = new RealTimeServerTcpConnectionManager();
    
    m_SipPeerToPeerEndpoint = new SipPeerToPeerEndpoint(textBoxSipUri.Text,
      m_RealTimeServerConnectionManager,
      SipTransportType.Tcp,
      textBoxDomainName.Text,
      5060);
    
  4. Double-click the New button and then add the following code to the button's event handler.

    Copy Code
    Form2 notificationForm = new Form2(this);
    notificationForm.Show();
    

To add code to Form2

  1. Add the following declarations above the Form2 constructor.

    Copy Code
    private NotificationOperation m_Broadcast;
    private Form1 m_ParentForm;
    
  2. Add the following parameter to the Form2 declaration.

    Copy Code
    Form1 Parent
    
  3. Add the following statement in the Form2 constructor, following the call to the InitializeComponent method.

    Copy Code
    m_ParentForm = Parent;
    
  4. Double-click the Send button and add the following statement to the button's event handler.

    Copy Code
    m_Broadcast = new NotificationOperation(textBoxMessage.Text, textBoxDestination.Text, m_ParentForm.m_SipPeerToPeerEndpoint, backgroundWorker1);
    

To add code to BroadcastIM.cs

  1. Add the following using statements to BroadcastIM.cs.

    Copy Code
    using Microsoft.Rtc.Signaling;
    using System.ComponentModel;
    using System.Net;
    using System.Net.Mime;
    
  2. Replace the BroadcastIM class with the following code.

    Copy Code
    public class NotificationOperation : IOfferAnswer
    {
    }
    
  3. Add the following declarations to the BroadcastIM class.

    Copy Code
    private String m_Notification;
    private String m_Destination;
    private SipPeerToPeerEndpoint m_Endpoint;
    private BackgroundWorker m_Worker;
    
  4. Add the following constructor to the BroadcastIM class.

    Copy Code
    public NotificationOperation(String Notification, String Destination, SipPeerToPeerEndpoint endpoint, BackgroundWorker Worker)
    {
      m_Notification = Notification;
      m_Destination = Destination;
    
      if (endpoint != null)
      {
    	m_Endpoint = endpoint;
      }
      else
      {
    	throw new InvalidOperationException("Cannot pass a null endpoint to the Notification Operation");
      }
    
      //Set the destination address. 
      Target To = new Target();
      To.SipUri = m_Destination;
    
      m_Worker = Worker;
      SignalingSession Session = new SignalingSession(m_Endpoint, new RealTimeAddress(To.SipUri));
      Session.LocalParticipant.ApplicationContext = To;
      Session.OfferAnswerNegotiation = this;
      Session.BeginParticipate(ParticipateCallback, Session);
    }
    
  5. Add the following members to the class.

    Copy Code
    //Callback for the BeginParticipate method.
    private void ParticipateCallback(IAsyncResult ar)
    {
      SignalingSession Session = ar.AsyncState as SignalingSession;
      Target To = Session.LocalParticipant.ApplicationContext as Target;
      SipMessageData Response = null;
    
      try
      {
    	Response = Session.EndParticipate(ar);
      }
      catch (OperationTimeoutException e)
      {
    	string msg = e.ToString();
      }
      catch (FailureResponseException e)
      {
    	string msg = e.ToString();
      }
      catch (ConnectionFailureException e)
      {
    	string msg = e.ToString();
      }
      catch (RealTimeException e)
      {
    	string msg = e.ToString();
      }
      finally
      {
    	if (Response != null)
    	{
    	Session.BeginSendMessage(MessageType.Message, new ContentType("text/plain"), Encoding.UTF8.GetBytes(m_Notification), SendMessageCallback, Session);
    }
      }
    }
    
    //Callback for the BeginSendMessage method.
    private void SendMessageCallback(IAsyncResult ar)
    {
      SignalingSession Session = ar.AsyncState as SignalingSession;
      SipResponseData Response = null;
      Target To = (Target)Session.LocalParticipant.ApplicationContext;
    
      try
      {
    	Response = Session.EndSendMessage(ar);
      }
      catch (FailureResponseException e)
      {
    	string msg = e.ToString();
      }
      catch (OperationTimeoutException e)
      {
    	string msg = e.ToString();
      }
      catch (RealTimeException e)
      {
    	string msg = e.ToString();
      }
      finally
      {
    	Session.BeginTerminate(TerminateCallback, Session);
      }
    }
    
    Callback for the BeginTerminate method.
    private void TerminateCallback(IAsyncResult ar)
    {
      SignalingSession Session = ar.AsyncState as SignalingSession;
      Session.EndTerminate(ar);
    }
    
    public ContentDescription GetOffer(object sender)
    {
      SignalingSession Session = sender as SignalingSession;
      IPAddress IpAddress;
    
      // This method is called back every time an outbound INVITE is sent.
      if (Session.Connection != null)
      {
    	IpAddress = Session.Connection.LocalEndpoint.Address;
      }
    
      else
      {
    	IpAddress = IPAddress.Any;
      }
    
      Sdp<SdpGlobalDescription, SdpMediaDescription> SessionDescription = new Sdp<SdpGlobalDescription, SdpMediaDescription>();
    
      //Set the origin line of the SDP
      //s, t, and v lines are automatically constructed
      SessionDescription.GlobalDescription.Origin.Version = 0;
      SessionDescription.GlobalDescription.Origin.SessionId = "0";
      SessionDescription.GlobalDescription.Origin.UserName = "-";
      SessionDescription.GlobalDescription.Origin.Connection.Set(IpAddress.ToString());
    
      //Set the connection line
      SessionDescription.GlobalDescription.Connection.TrySet(IpAddress.ToString());
    
      SdpMediaDescription mditem = new SdpMediaDescription("message");
    
      mditem.Port = 5060;
      mditem.TransportProtocol = "sip";
      mditem.Formats = "null";
    
      SdpAttribute aitem = new SdpAttribute("accept-types", "text/plain");
    
      mditem.Attributes.Add(aitem);
    
      //Append the Media description to the Global description
      SessionDescription.MediaDescriptions.Add(mditem);
    
      ContentType ct = new ContentType("application/sdp");
    
      return new ContentDescription(ct, SessionDescription.GetBytes());
    
    }
    
    //Required interface member.
    public ContentDescription GetAnswer(object sender, ContentDescription offer)
    {
      return null;
    }
    
    //Required interface member.
    public void SetAnswer(object sender, ContentDescription answer)
    {
      return;
    }
    
    //Required interface member.
    public void HandleOfferInInviteResponse(object sender, OfferInInviteResponseEventArgs e)
    {
      return;
    }
    
    //Required interface member.
    public void HandleOfferInReInvite(object sender, OfferInReInviteEventArgs e)
    {
      return;
    }
    
  6. Add the Target class to BroadcastIM.cs.

    Copy Code
    //This class stores the SIP URI of the 
    //distribution group receiving the broadcast.
    public class Target
    {
      string m_SipUri;
      public string SipUri
      {
    	get
    	{
    	return m_SipUri;
    }
    
    	set
    	{
    	SipUriParser TargetUri;
    
    	if (SipUriParser.TryParse(value, out TargetUri))
    	{
    		m_SipUri = value;
    }
    
    	else
    	{
    		throw new InvalidOperationException("Cannot assign the current value");
    }
    
    }
      }
    }
    
  7. Build the solution.

To run the application

  1. Add your sample to the authorized list of hosts on Office Communications Server and then enable server throttling.

  2. Press F5.

  3. On Form1, in Domain Name, enter the domain name of the Office Communications Server.

  4. In SIP URI, enter a URI using this style: sip:someone@example.com. This value is transmitted in the message header as the sender's name.

  5. Click Set, and then click New.

  6. On Form2, in Message, enter a message for broadcast.

  7. In Destination, enter the SIP address that will receive the message.

  8. Click Send.

See Also