0

We have a UCMA 3.0 based application/bot that matches end users with experts. It migrates incoming one-one chat requests from end users into a multi user conference and then invites experts into the resulting multi user conference. The application itself continues to be a participant in the conference. At any given time, there may be several such conferences being brokered by our application but only one per end user. However, a single expert may be participating in more than one conference at the same time. In our application logs we occasionally see the following exception.

Error in Conference Migration conf call # 63809878 ,Address :sip:xxxxxx@xxx.com;gruu;opaque=app:conf:focus:id:TQRREACE System.InvalidOperationException: Cannot join a different conference after receiving a conference invitation or conference escalation request. at Microsoft.Rtc.Collaboration.ConferenceSession.VerifyAndGetConferenceAddress(String conferenceUri, String parameterName) at Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoinCommon(String conferenceUri, ConferenceJoinOptions options, AsyncCallback userCallback, Object state) at Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoin(String conferenceUri, ConferenceJoinOptions options, AsyncCallback userCallback, Object state) at a(String A_0, String A_1, String A_2, Boolean A_3, Boolean A_4)

Below is the code snippet used to make conference. Previously this site was an OCS 2007 R2 Installation and was migrated to Lync 2010 Server.
Site is running in mixed mode. It occurs only on production server and we are not able to generate this exception on dev server, we 
have tested it after generating more than 15 conferences simultaniously but no luck. 

private void CreateAdHohConf(string user1Uri, string user2uri, string subject) { Exception exception = null;

            // Create conference scheduling details for the conference.
            ConferenceScheduleInformation scheduleInfo = new ConferenceScheduleInformation();

            // Restrict the conference to invited users only.
            scheduleInfo.AccessLevel = ConferenceAccessLevel.Everyone;


            // Set a subject for the conference.
            scheduleInfo.Subject = subject;
            scheduleInfo.Description = subject;
            scheduleInfo.ConferenceId = ConferenceServices.GenerateConferenceId();
            scheduleInfo.ExpiryTime = System.DateTime.Now.AddHours(8);
            scheduleInfo.IsPasscodeOptional = true;
            scheduleInfo.PhoneAccessEnabled = false;

            // Don't automatically assign a leader.
            scheduleInfo.AutomaticLeaderAssignment = AutomaticLeaderAssignment.Everyone;

            // Add the caller and recipient as participants.
            scheduleInfo.Participants.Add(new ConferenceParticipantInformation("sip:" + user1Uri, ConferencingRole.Leader));
            scheduleInfo.Participants.Add(new ConferenceParticipantInformation("sip:" + user2uri, ConferencingRole.Leader));

            scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.ApplicationSharing));
            scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.InstantMessaging));
            scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.AudioVideo));
            scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.Meeting));

             //Scheduling conference

            ConferenceServices objLocalConfSvc = lyncAgent.LocalEndpoint.ConferenceServices;
            Conference confSession = null;
            objLocalConfSvc.BeginScheduleConference(scheduleInfo,
                result =>
                {
                    try
                    {
                        confSession = objLocalConfSvc.EndScheduleConference(result);

                    }
                    catch (RealTimeException rtex)
                    {
                        exception = rtex;

                    }
                    catch (Exception ex)
                    {
                        exception = ex;

                    }
                    finally
                    {
                        _waitForConferenceScheduling.Set();
                    }
                }, objLocalConfSvc);

            _waitForConferenceScheduling.WaitOne();


            //Begin Join conference
           ConferenceSession objLocalConfSession=this.call.Conversation.ConferenceSession;
            try
            {
                ConferenceJoinOptions joinOptions = new ConferenceJoinOptions() { CanManageLobby = false, JoinMode = JoinMode.Default };
                objLocalConfSession.BeginJoin(new RealTimeAddress(confSession.ConferenceUri).Uri, joinOptions,
                    result => {
                        try
                        {
                            objLocalConfSession.EndJoin(result);
                        }
                        catch (Exception ex)
                        {
                            exception = ex;

                        }
                        finally
                        {
                            //Again, for sync. reasons.
                            _waitForConferenceJoin.Set();
                        }
                    }
                , this.call.Conversation.ConferenceSession);
                // Wait until join completes.new RealTimeAddress(this._conference.ConferenceUri).Uri,
                _waitForConferenceJoin.WaitOne();
            }
            catch (InvalidOperationException ioex)
            {
                exception = ioex;

            }
            catch (Exception ex)
            {
                exception = ex;

            }

            //Begin Escalation
          Conversation objLocalConv= this.call.Conversation;
          try
          {
              objLocalConv.BeginEscalateToConference(
                  result =>
                  {
                      try
                      {
                          objLocalConv.EndEscalateToConference(result);
                      }
                      catch (Exception ex)
                      {
                          exception = ex;

                      }
                      finally
                      {
                          //Sync It
                          _waitForEscalation.Set();
                      }
                  }
                      , objLocalConv);
              // Wait until escalation completes.
              _waitForEscalation.WaitOne();
          }
          catch (InvalidOperationException ioex)
          {
              exception = ioex;
          }
          catch (Exception ex)
          {
              exception = ex;
          }
          finally
          {
              if (exception != null)
              {
                  lyncAgent.Logger.Error( "Error in Conference Migration conf call # " + GetHashCode() + " , Address :" + confSession.ConferenceUri  , exception);
              }
          }
        }

Please suggest what could be the possible problem on priority basis.

        Thanks in advance.
Krishna
  • 36
  • 4

2 Answers2

0

Does this method reside in an object where it is possible that it will be called by multiple sources at the same time?

If so, using what appears to be a class level variable like _waitForConferenceScheduling could be problematic. Thread A could end up accidentally letting Thread B proceed before Thread B's async action is actually completed. So Thread B could call .BeginEscalate before .EndJoin was called.

When I write UCMA code, I generally use nested callbacks to prevent this type of thing from happening.

Other than that, I'd recommend you run OCSLogger on your application server and the Lync Front End server to gather SIPStack, S3 and Collaboration logs. Looking at the actual SIP messages in detail will provide some clues.

You'd be looking for an INVITE to the conference and the response back to that INVITE.

Peter M
  • 472
  • 5
  • 16
  • We have already tested the code without wait handlers and using call back methods like : lyncAgent.LocalEndpoint.ConferenceServices.BeginScheduleConference(scheduleInfo, OnConferenceScheduleCompleted, lyncAgent.LocalEndpoint.ConferenceServices); But still we are getting same error. – Krishna May 03 '12 at 10:41
0

We managed to detect the reason. It happens if any one in the participant list have already added any contact for meeting in conversation with our endpoint.