0

我们有一个基于 UCMA 3.0 的应用程序/机器人,可以将最终用户与专家相匹配。它将来自最终用户的传入一对一聊天请求迁移到多用户会议中,然后邀请专家参加由此产生的多用户会议。应用程序本身仍然是会议的参与者。在任何给定时间,我们的应用程序可能会代理多个此类会议,但每个最终用户只有一个。但是,一位专家可能同时参加多个会议。在我们的应用程序日志中,我们偶尔会看到以下异常。

Conference Migration conf call # 63809878 中的错误,地址:sip:xxxxxx@xxx.com;gruu;opaque=app:conf:focus:id:TQRREACE System.InvalidOperationException:收到会议邀请或会议升级请求后无法加入其他会议. 在 Microsoft.Rtc.Collaboration.ConferenceSession.VerifyAndGetConferenceAddress(String meetingUri, String parameterName) 在 Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoinCommon(String meetingUri, ConferenceJoinOptions options, AsyncCallback userCallback, Object state) 在 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. 

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

请建议优先考虑可能存在的问题。

        Thanks in advance.
4

2 回答 2

0

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

于 2013-02-03T04:47:04.993 回答
0

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

如果是这样,使用像 _waitForConferenceScheduling 这样的类级别变量可能会出现问题。在线程 B 的异步操作实际完成之前,线程 A 可能会意外地让线程 B 继续进行。所以线程 B 可以在调用 .EndJoin 之前调用 .BeginEscalate。

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

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

您将寻找参加会议的邀请以及对该邀请的回复。

于 2012-05-02T22:33:29.460 回答