Partager via


Walkthrough: Start an Audio Conversation (Lync 2010 SDK)

This topic demonstrates how to start an audio conversation. This process involves creating a conversation with a local and remote participant, and connecting to the remote participant using the participant’s AudioVideo (AV) modality. To complete this walkthrough, you must handle state change events on both the client’s ConversationManager instance and the conversation itself.

Starting an Audio Conversation

The following figure illustrates the classes, methods, and events used in the process of starting an audio conversation.

Hh378584.OCOM_StartAudioConversation(en-us,office.14).png

Start an Audio Conversation

  1. Create a callback method that handles the ConversationAdded event.

  2. Create a callback method that handles the ParticipantAdded event.

  3. Get the LyncClient instance. Verify that the client is signed in to the server. For information about signing in to Microsoft Lync Server 2010, see Walkthrough: Sign In to Lync (Lync 2010 SDK)

  4. Get the ConversationManager instance by reading the ConversationManager property of the LyncClient class instance.

  5. Register for the ConversationAdded event on the ConversationManager instance.

  6. Call the AddConversation method on the ConversationManager instance.

Handling Events

ConversationAdded Event

  1. Check the modality state of the audio/video modality on the added conversation. If the modality is ModalityState.Notified then conversation was not started by the local user. For this walkthrough, you handle the event for only the conversation added by the local user.

    Tip

    The ConversationAdded event is raised when either a local user starts a conversation or a remote user invites the local user to a new conversation.

  2. Register for state change events on the conversation.

  3. Call the CanInvoke method and pass ConversationAction.AddParticipant

  4. If you can add a participant, get a Contact instance to add to the conversation by calling into GetContactByUri. A contact that resolves to the passed Uri is returned.

  5. Call the AddParticipant method on the conversation. Pass the Contact instance from the prior step as the contact argument.

Important

You must register for and handle events on both locally originated conversations and conversations you obtain by accepting an invitation from a remote user.

ParticipantAdded Event

  1. Read the IsSelf property of the added participant exposed by Participant property. The following steps should not be executed for the self-participant.

  2. Get the AVModality from the Modalities property of the conversation in the source parameter of the callback method: source.Modalities[ModalityTypes.AudioVideo]

  3. Cast the obtained Modality class instance to AVModality.

  4. Register for ModalityStateChanged on the audio/video modality to catch the ModalityState.Connected event that is raised after you connect to the modality.

  5. Register for participant events on the remote participant.

  6. Call the BeginConnect method on this AVModality instance to allow both the local and remote endpoints to accept the conversation. You must call EndConnect after calling BeginConnect. You can call EndConnect on your UI thread or you can call it within a System.AsyncCallback method you pass into BeginConnect.

Examples

This walkthrough assumes that you have created a Windows.Forms object and populated it with a textbox for entry of a contact’s URI and a button that you use to start a conversation. If you create a WPF application and use this example code, you must marshal event data using System.Windows.Threading.Dispatcher.BeginInvoke(Delegate, Object[]).

The following example creates a new conversation by calling into the AddConversation method on an instance of the ConversationManager.

Declarations

The following declarations provide this example with the ability to marshal event data to the UI thread from the Lync 2010 thread. UIUpdater is invoked using the UpdateFormControlDelegate so that updates to controls on the UI can be made.

using System;
using System.Windows.Forms;
using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Conversation;
using Microsoft.Lync.Model.Conversation.AudioVideo;

namespace CustomAudioConversation
{

    public partial class MainForm : Form
    {
        private string targetUri;
        private Conversation _Conversation;
        private LyncClient _LyncClient;
...

Start a Conversation

The following example registers for conversation manager events and starts the conversation. Assume the LyncClient was obtained using the walkthrough steps found in Walkthrough: Sign In to Lync with UI Suppressed (Lync 2010 SDK).



public void StartConversation()
{
   _LyncClient.ConversationManager.ConversationAdded += ConversationManager_ConversationAdded;
   _Conversation = _LyncClient.ConversationsManager.AddConversation();
}

ConversationManager Events

The following example registers for conversation instance events and adds a participant to the new conversation after verifying that the added conversation is the one started in the previous example.

        /// <summary>
        /// Called on the LyncClient worker thread by the ConversationManager instance when a conversation has been
        /// added to the Conversations collection on ConversationManager.
        /// A conversation is added when ConversationManager.AddConversation() is called on the UI thread or when a remote user
        /// is calling the local user.
        /// </summary>
        /// <param name="sender">object. A ConversationManager instance.</param>
        /// <param name="e">ConversationManagerEventArgs. The event state data object.</param>
        void ConversationManager_ConversationAdded(object sender, ConversationManagerEventArgs e)
        {
            //Conversation originated with remote SIP user
            if (e.Conversation.Modalities[ModalityTypes.AudioVideo].State != ModalityState.Notified)
            {
                if (e.Conversation.CanInvoke(ConversationAction.AddParticipant)
                {
                    e.Conversation.ParticipantAdded += Conversation_ParticipantAdded;
                    e.Conversation.AddParticipant(_LyncClient.ContactManager.GetContactByUri("bob@contoso.com"));
                }
            }
        }

Conversation Events

The previous example added a participant. This example handles the event raised when the participant is added. It obtains the AVModality of the new conversation and begins to connect to the remote participant using this modality. When the modality is connected, a state change event for the modality is raised.

Tip

A collection of modalities is also surfaced by the new participant but you do not connect to the remote participant using these. The participant modality collection is only used for instant messaging.

        /// <summary>
        /// ParticipantAdded callback handles ParticpantAdded event raised by Conversation
        /// </summary>
        /// <param name="source">Conversation Source conversation.</param>
        /// <param name="data">ParticpantCollectionEventArgs Event data</param>
        void Conversation_ParticipantAdded(object source, ParticipantCollectionChangedEventArgs data)
        {
            if (data.Participant.IsSelf != true)
            {
                if (((Conversation)source).Modalities[ModalityTypes.AudioVideo].CanInvoke(ModalityAction.Connect))
                {
                    object[] asyncState = { ((Conversation)source).Modalities[ModalityTypes.AudioVideo], "CONNECT" };
                    try
                    {
                         ((Conversation)source).Modalities[ModalityTypes.AudioVideo].ModalityStateChanged += _AVModality_ModalityStateChanged;
                         ((Conversation)source).Modalities[ModalityTypes.AudioVideo].BeginConnect(ModalityConnectOptions.None, ModalityCallback, asyncState);
                    }
                    catch (LyncPlatformException ce)
                    {
                        throw new Exception("Lync Platform Exception on BeginConnect: " + ce.Message);
                    }
                }
            }
        }

Conversation Modality Operation Callback

The following example calls EndConnect to complete the connect operation. Because several different modality operations can be executed, it is important that your callback method determines which started operation triggers the asynchronous callback. The example uses the asynchronous state property of IAsyncResult to indicate the operation that was started on the UI thread.

Calling the EndConnect method in the callback instead of in the UI thread prevents the example application from blocking while the call is connected.

        /// <summary>
        /// Called on the LyncClient worker thread when an audio/video modality action completes.
        /// </summary>
        /// <param name="ar">IAsyncResult. The state of the asynchronous operation.</param>
        private void ModalityCallback(IAsyncResult ar)
        {
            Object[] asyncState = (Object[])ar.AsyncState;
            try
            {
                if (ar.IsCompleted == true)
                {
                    if (asyncState[1].ToString() == "RETRIEVE")
                    {
                        ((AVModality)asyncState[0]).EndRetrieve(ar);
                    }
                    if (asyncState[1].ToString() == "HOLD")
                    {
                        ((AVModality)asyncState[0]).EndHold(ar);
                    }
                    if (asyncState[1].ToString() == "CONNECT")
                    {
                        ((AVModality)asyncState[0]).EndConnect(ar);
                    }
                    if (asyncState[1].ToString() == "FORWARD")
                    {
                        ((AVModality)asyncState[0]).EndForward(ar);
                    }
                }
            }
            catch (LyncPlatformException)
            { }
        }

Modality Events

This example handles the modality state change event that is raised when the conversation audio/video modality has connected to the remote participant.

Warning

You may experience an eventing delay after a participant endpoint has disconnected from a modality. For example, if an attempt to connect a participant to the audio modality ends in failure because the telephone number that was called is busy, you may not receive a modality state change event for the disconnect immediately.

        /// <summary>
        /// Handles the Modality state changed event for a Conversation
        /// </summary>
        /// <param name="source">Modality. Modality whose state has changed.</param>
        /// <param name="data">ModalityStateChangedEventArgs. Old and new modality states.</param>
        void _AVModality_ModalityStateChanged(object sender, ModalityStateChangedEventArgs e)
        {
            switch (e.NewState)
            {
                case ModalityState.Connected:
                    MessageBox.Show(″Conversation audio is connected. You should say hello now.″);
                    break;
            }
        }

See Also

Tasks

Walkthrough: Sign In to Lync with UI Suppressed (Lync 2010 SDK)

Concepts

Walkthrough: Start a Video Conversation (Lync 2010 SDK)

Lync Model API Conversation Walkthroughs (Lync 2010 SDK)