To make it possible for developers to extend the functionality of Lync without having to deal with the nitty-gritty details of Session Initiation Protocol (a.k.a. SIP), UCMA introduces a lot of abstractions. One of the abstractions that pops up most frequently is the Conversation class. Unfortunately, it’s also one of the most confusing to new UCMA developers. This is partly because its purpose isn’t immediately obvious when you start doing things like sending IMs or answering audio calls.
If you’ve worked much with UCMA, you know that to start a new audio call, for example, you need to do something like the following:
Conversation conversation = new Conversation(_endpoint); AudioVideoCall avCall = new AudioVideoCall(conversation); avCall.BeginEstablish("sip:email@example.com", null, OnCallEstablished, avCall); ...
There’s no way to create a new call without first creating a Conversation object. One question that often comes up is: Why do you need a Conversation object when you’ve got AudioVideoCall to represent your new call? What good is Conversation?
The answer has to do with the way Lync handles multi-modality communication. What do I mean by “multi-modality communication”? If you think about what Lync does when you’re having an IM conversation with someone, and you add audio from the IM window, that’s a multi-modality conversation. Under the covers, when Lync sends out a new SIP INVITE message to initiate a call, IM, etc., it contains a SIP header called Ms-Conversation-ID, looking more or less like this:
If you later add a different modality (e.g., you add application sharing to your audio call), Lync will reuse the same Ms-Conversation-ID in the new SIP INVITE message. This conversation ID effectively ties your different modalities together into a single communication session.
Getting back to UCMA, the Conversation object represents one of these multi-modality communication sessions. To put it another way, a Conversation object is a way of managing one or more calls (Call objects, in UCMA) that have the same conversation ID.
In the code example I gave above, if after establishing your A/V call you wanted to add the IM modality, you would use the same instance of Conversation.
InstantMessagingCall imCall = new InstantMessagingCall(avCall.Conversation);
This tells UCMA that you’re not creating a completely separate IM call; instead, you’re adding the IM modality to an existing conversation which already includes an A/V call.
I hope this helps to clarify a bit what the Conversation class is for. If you have questions, feel free to ask in the comments!