This documentation is archived and is not being maintained.

Walkthrough: Send Text Alerts

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 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:

  • Connecting to Active Directory and extracting member addresses from a distribution group is not included.
  • Transport Layer Security (TLS) is not used. Transmission Control Protocol (TCP) is used. Regardless of its use in this sample, using TCP in production environments is not recommended. Use TLS in production environments.
  • Application progress updates are not provided.

Create a new Microsoft Windows Visual C# application.

  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 to the three files.

  1. Add the following using statement to Form1.

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

    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.

    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.

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

  1. Add the following declarations above the Form2 constructor.

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

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

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

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

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

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

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

    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.

    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.

    //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.

    //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.

  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.

Show: