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.

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

  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 . Notifiedthen 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 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 note 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 sourceparameter 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 . Connectedevent 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 EndConnecton your UI thread or you can call it within a System.AsyncCallbackmethod 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. UIUpdateris invoked using the UpdateFormControlDelegateso that updates to controls on the UI can be made.

C#  Copy imageCopy Code
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 .

C#  Copy imageCopy Code


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.

C#  Copy imageCopy Code
		/// <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 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.

C#  Copy imageCopy Code
		/// <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 IAsyncResultto 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.

C#  Copy imageCopy Code
		/// <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.

C#  Copy imageCopy Code
		/// <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