2012-04-30 39 views
0

我们有一个基于UCMA 3.0的应用程序/机器人,可将最终用户与专家匹配。它将来自最终用户的传入一对一聊天请求迁移到多用户会议中,然后邀请专家参加最终的多用户会议。应用程序本身仍然是会议的参与者。在任何时候,可能会有几个这样的会议由我们的应用程序斡旋,但每个最终用户只有一个。但是,一位专家可能同时参加多个会议。 在我们的应用程序日志中,我们偶尔会看到以下异常。UCMA 3.0 API会议错误:在收到会议邀请或会议升级请求后无法加入不同的会议

会议迁移conf错误#63809878,地址:sip:[email protected]; gruu; opaque = app:conf:focus:id:TQRREACE System.InvalidOperationException:收到会议邀请后无法加入其他会议或会议升级请求。 在Microsoft.Rtc.Collaboration.ConferenceSession.VerifyAndGetConferenceAddress(字符串conferenceUri,字符串parameterName)以 在Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoinCommon(字符串conferenceUri,ConferenceJoinOptions选项的AsyncCallback userCallback,对象状态) 在Microsoft.Rtc.Collaboration。 ConferenceSession.BeginJoin(字符串conferenceUri,ConferenceJoinOptions选项,AsyncCallback的userCallback,对象状态) 在(字符串A_0,A_1字符串,字符串A_2,A_3布尔,布尔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. 

私人无效CreateAdHohConf(字符串user1Uri,串user2uri,string subject) { 离子异常=空;

  // 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); 
       } 
      } 
     } 

请建议优先考虑什么是可能的问题。

 Thanks in advance. 

回答

0

此方法是否驻留在可能由多个源同时调用的对象中?

如果是这样,使用看起来像_waitForConferenceScheduling这样的类级变量可能会有问题。线程A最终可能会在线程B的异步操作实际完成之前意外地让线程B继续。因此线程B可以在调用.BeginEscalate之前调用.EndJoin。

当我编写UCMA代码时,我通常使用嵌套回调来防止发生这种类型的事情。

除此之外,我建议您在应用程序服务器和Lync前端服务器上运行OCSLogger以收集SIPStack,S3和协作日志。详细查看实际的SIP消息将提供一些线索。

你会寻找会议的邀请和回复该邀请的响应。

+0

我们已经测试的代码,而无需等待处理,并使用回拨类似的方法:lyncAgent.LocalEndpoint.ConferenceServices.BeginScheduleConference(scheduleInfo,OnConferenceScheduleCompleted,lyncAgent.LocalEndpoint.ConferenceServices);但我们仍然得到同样的错误。 – Krishna

0

我们设法检测到原因。如果参与者列表中的任何人已添加了与我们的端点进行会话的会议的任何联系人,就会发生这种情况。