Timeout UCMA会议电话在第一次参与者建立时卡住

Timeout UCMA会议电话在第一次参与者建立时卡住,timeout,call,lync,ucma,conference,Timeout,Call,Lync,Ucma,Conference,我正在尝试使用UCMA 4.0基本会议示例和第一个用户端点(lync没有响)来启动会议。超时异常在一段时间后触发。主要问题是什么 顺便说一句,平台已经启动,发现了3个已建立的应用程序端点 sip:kl.dev。local@dev.local;格鲁;不透明=srvr:yyapp:ehghh8uxnvqiedxu3ygjyqayyapp sip:kl.cdev。local@dev.local;格鲁;不透明=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine1 sip

我正在尝试使用UCMA 4.0基本会议示例和第一个用户端点(lync没有响)来启动会议。超时异常在一段时间后触发。主要问题是什么

顺便说一句,平台已经启动,发现了3个已建立的应用程序端点

sip:kl.dev。local@dev.local;格鲁;不透明=srvr:yyapp:ehghh8uxnvqiedxu3ygjyqayyapp sip:kl.cdev。local@dev.local;格鲁;不透明=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine1 sip:kl.dev。local@dev.local;格鲁;不透明=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine2 sip:kl.dev。local@dev.local;格鲁;不透明=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine3 'LyncGame.Gateway.TestConnection.vshost.exe'(CLR v4.0.30319:LyncGame.Gateway.TestConnection.vshost.exe):加载'C:\Windows\Microsoft.Net\assembly\GAC\U MSIL\System.Data.SqlXml\v4.0\U 4.0.0\UUUU B77A561934E089\System.Data.SqlXml.dll'。已跳过加载符号。模块已优化,并且调试器选项“仅我的代码”已启用。 “LyncGame.Gateway.TestConnection.vshost.exe”(CLR v4.0.30319:LyncGame.Gateway.TestConnection.vshost.exe):已加载“System.Xml.Xsl.CompiledQuery.1”。 线程0x6e8已退出,代码为259(0x103)。 线程0x3dd4已退出,代码为259(0x103)。 线程0x2138已退出,代码为259(0x103)。 “LynchGame.Gateway.TestConnection.vshost.exe”(CLR v4.0.30319:LynchGame.Gateway.TestConnection.vshost.exe):加载了“C:\Windows\Microsoft.Net\assembly\GAC\U MSIL\System.Security\v4.0.0.0\UU b03f5f7f11d50a3a\System.Security.dll”。已跳过加载符号。模块已优化,并且调试器选项“仅我的代码”已启用。 线程0x3180已退出,代码为259(0x103)。 线程0x350c已退出,代码为259(0x103)。 线程0x1698已退出,代码为0(0x0)。 线程0x3ef4已退出,代码为0(0x0)。 线程0x3f00已退出,代码为259(0x103)。 线程0x2a24已退出,代码为259(0x103)。 线程0x3fc0已退出,代码为259(0x103)。 线程0x3750已退出,代码为259(0x103)。 线程0x27b8已退出,代码为259(0x103)。 线程0x11e0已退出,代码为259(0x103)。 线程0x2214已退出,代码为259(0x103)。 线程0x1564已退出,代码为259(0x103)。 线程0x3740已退出,代码为259(0x103)。 线程0x28a8已退出,代码为259(0x103)。 线程0x1da8已退出,代码为259(0x103)。 Microsoft.Rtc.Collaboration.dll中发生了类型为“Microsoft.Rtc.Signaling.OperationTimeoutException”的首次意外异常

类UCMAConference
{
#本地人
//加入MCU时要发送的IM。
私有静态字符串_messageToSend=“你好,世界!”;
非公开会议;
私有应用程序点_callerEndpoint,_calleendpoint;
//等待句柄的存在只是为了保持同步和易于阅读。
私有自动恢复事件_waitForCallEstablish=新自动恢复事件(false);
私有自动恢复事件_waitForConferenceScheduling=新自动恢复事件(false);
私有自动恢复事件_waitForConferenceJoin=新自动恢复事件(false);
private AutoResetEvent_waitForMessageReceived=新的AutoResetEvent(false);
private AutoResetEvent_WaitFormMessage2Received=新的AutoResetEvent(假);
私有自动恢复事件waitForUserEndpointEstablish=新自动恢复事件(false);
私有自动重置事件_waitForShutdown=新自动重置事件(false);
私有自动resetevent _waitForConversationInviteRemoteParticipants=新自动resetevent(false);
私有InstantMessageFlow _IMFlow;
私有InstantMessageFlow _IMFlow2;
#端区
公开会议StartConference()
{
尝试
{
foreach(PlatformDataProvider.DataProvider.AppEndpoints中的变量项)
{
WriteLog.AddLine(item.EndpointUri+item.OwnerDisplayName);
Console.WriteLine(item.EndpointUri+item.OwnerDisplayName);
}
//创建端点的步骤
UCMACoach UCMACoach=新UCMACoach();
UserEndpointSettings设置=新的UserEndpointSettings(“sip:user8@dev.local");
UserEndpoint _UserEndpoint=新的UserEndpoint(PlatformDataProvider.DataProvider.CollabPlatform,设置);
_userEndpoint.BeginEstablish(ar=>
{
尝试
{
_userEndpoint.EndEstablish(ar);
waitForUserEndpointEstablish.Set();
}
捕获(例外情况除外)
{
WriteLog.AddLine(“建立时出错:+ex.Message”);
waitForUserEndpointEstablish.Set();
}
},空);
waitForUserEndpointEstablish.WaitOne();
AddLine(“已建立用户端点”);
_userEndpoint.LocalOwnerPresence.BeginSubscribe(r=>
{
},空);
//IAsyncResult result=\u userEndpoint.LocalOwnerPresence.BeginPublishPresence(Microsoft.Rtc.Collaboration.Presence.Presence.PresenceAvailability.Busy);
//使用网络凭据对象创建用户端点
//定义见上文。
_callerEndpoint=PlatformDataProvider.DataProvider.AppEndpoints[1];
/*会议负责人端点的友好名称*/
//使用网络凭据对象创建第二个用户端点
//定义见上文。
_calleeEndpoint=PlatformDataProvider.DataProvider.AppEndpoints[2];
/*会议与会者终结点的友好名称*/
//获取登录到Microsoft Lync的用户的URI
String_ocUserURI=“sip:user9@dev.local";
//其中一个端点提前安排会议。在
//计划时间,所有会议设置均已设置。
//英国广播公司
class UCMAConference
{
    #region Locals
    // The IM to send upon joining the MCU.
    private static String _messageToSend = "Hello, World!";

    private Conference _conference;

    private ApplicationEndpoint _callerEndpoint, _calleeEndpoint;

    //Wait handles are only present to keep things synchronous and easy to read.
    private AutoResetEvent _waitForCallEstablish = new AutoResetEvent(false);

    private AutoResetEvent _waitForConferenceScheduling = new AutoResetEvent(false);

    private AutoResetEvent _waitForConferenceJoin = new AutoResetEvent(false);

    private AutoResetEvent _waitForMessageReceived = new AutoResetEvent(false);

    private AutoResetEvent _waitForMessage2Received = new AutoResetEvent(false);

    private AutoResetEvent waitForUserEndpointEstablish = new AutoResetEvent(false);

    private AutoResetEvent _waitForShutdown = new AutoResetEvent(false);

    private AutoResetEvent _waitForConversationInviteRemoteParticipants = new AutoResetEvent(false);

    private InstantMessagingFlow _IMFlow;

    private InstantMessagingFlow _IMFlow2;
    #endregion

    public Conference StartConference()
    {
        try
        {
            foreach (var item in PlatformDataProvider.DataProvider.AppEndpoints)
            {
                WriteLog.AddLine(item.EndpointUri + item.OwnerDisplayName);
                Console.WriteLine(item.EndpointUri + item.OwnerDisplayName);
            }
            // to create end point(s)
            UCMACoach ucmaCoach = new UCMACoach();
            UserEndpointSettings settings = new UserEndpointSettings("sip:user8@dev.local");

            UserEndpoint _userEndpoint = new UserEndpoint(PlatformDataProvider.DataProvider.CollabPlatform, settings);
            _userEndpoint.BeginEstablish(ar =>
            {
                try
                {
                    _userEndpoint.EndEstablish(ar);
                    waitForUserEndpointEstablish.Set();
                }
                catch (Exception ex)
                {
                    WriteLog.AddLine("Error on establish: " + ex.Message);
                    waitForUserEndpointEstablish.Set();
                }

            }, null);
            waitForUserEndpointEstablish.WaitOne();


            WriteLog.AddLine("User endpoint has been established ");
            _userEndpoint.LocalOwnerPresence.BeginSubscribe(r =>
            {

            }, null);

            //IAsyncResult result = _userEndpoint.LocalOwnerPresence.BeginPublishPresence(Microsoft.Rtc.Collaboration.Presence.PresenceAvailability.Busy);
            // Create a user endpoint, using the network credential object
            // defined above.
            _callerEndpoint = PlatformDataProvider.DataProvider.AppEndpoints[1];
            /* friendly name for conference leader endpoint */

            // Create a second user endpoint, using the network credential object
            // defined above.
            _calleeEndpoint = PlatformDataProvider.DataProvider.AppEndpoints[2];
            /* friendly name for conference attendee endpoint */

            // Get the URI for the user logged onto Microsoft Lync
            String _ocUserURI = "sip:user9@dev.local";

            // One of the endpoints schedules the conference in advance. At 
            // schedule time, all the conference settings are set.

            // The base conference settings object, used to set the policies for the conference.
            ConferenceScheduleInformation conferenceScheduleInformation = new ConferenceScheduleInformation();
            // An open meeting (participants can join who are not on the list), 
            // but requiring authentication (no anonymous users allowed.)
            conferenceScheduleInformation.AccessLevel = ConferenceAccessLevel.SameEnterprise;
            // The below flag determines whether or not the passcode is optional
            // for users joining the conference.
            conferenceScheduleInformation.IsPasscodeOptional = true;
            conferenceScheduleInformation.Passcode = "1357924680";
            // The verbose description of the conference
            conferenceScheduleInformation.Description = "StartReady | Conference Testing";
            // The below field indicates the date and time after which the conference can be deleted.
            conferenceScheduleInformation.ExpiryTime = System.DateTime.Now.AddHours(5);

            // These two lines assign a set of modalities (here, only 
            // InstantMessage) from the available MCUs to the conference. Custom
            // modalities (and their corresponding MCUs) may be added at this 
            // time as part of the extensibility model.
            ConferenceMcuInformation instantMessageMCU = new ConferenceMcuInformation(McuType.InstantMessaging);
            conferenceScheduleInformation.Mcus.Add(instantMessageMCU);

            // Now that the setup object is complete, schedule the conference 
            // using the conference services off of Endpoint. Note: the conference
            // organizer is considered a leader of the conference by default.
            _callerEndpoint.ConferenceServices.BeginScheduleConference(conferenceScheduleInformation,
                EndScheduleConference, _callerEndpoint.ConferenceServices);

            // Wait for the scheduling to complete.
            _waitForConferenceScheduling.WaitOne();

            // Now that the conference is scheduled, it's time to join it. As we
            // already have a reference to the conference object populated from
            // the EndScheduleConference call, we do not need to get the 
            // conference first. Initialize a conversation off of the endpoint, 
            // and join the conference from the uri provided above.
            Conversation callerConversation = new Conversation(_callerEndpoint);
            callerConversation.ConferenceSession.StateChanged += new
                EventHandler<StateChangedEventArgs<ConferenceSessionState>>(ConferenceSession_StateChanged);

            // Join and wait, again forcing synchronization.
            callerConversation.ConferenceSession.BeginJoin(_conference.ConferenceUri, null /*joinOptions*/,
                EndJoinConference, callerConversation.ConferenceSession);
            _waitForConferenceJoin.WaitOne();

            // Placing the calls on the conference-connected conversation 
            // connects to the respective MCUs. These calls may then be used to
            // communicate with the conference/MCUs.
            InstantMessagingCall instantMessagingCall = new InstantMessagingCall(callerConversation);

            // Hooking up event handlers and then placing the call.
            instantMessagingCall.InstantMessagingFlowConfigurationRequested +=
                this.instantMessagingCall_InstantMessagingFlowConfigurationRequested;
            instantMessagingCall.StateChanged += this._call_StateChanged;
            instantMessagingCall.BeginEstablish(EndCallEstablish, instantMessagingCall);

            //Synchronize to ensure that call has completed.
            _waitForCallEstablish.WaitOne();

            //send conf invite
            ConferenceInvitationDeliverOptions deliverOptions = new ConferenceInvitationDeliverOptions();
            deliverOptions.ToastMessage = new ToastMessage("Welcome to conference of StartReady Demo");

            ConferenceInvitation invitation = new ConferenceInvitation(callerConversation);
            invitation.BeginDeliver(_ocUserURI, deliverOptions, EndDeliverInvitation, invitation);

            // Synchronize to ensure that invitation is complete
            _waitForConversationInviteRemoteParticipants.WaitOne();

            //And from the other endpoint's perspective:
            //Initialize a conversation off of the endpoint, and join the 
            //conference from the uri provided above.
            Conversation calleeConversation = new Conversation(_calleeEndpoint);
            calleeConversation.ConferenceSession.StateChanged += new
                EventHandler<StateChangedEventArgs<ConferenceSessionState>>(ConferenceSession_StateChanged);

            // Join and wait, again forcing synchronization.
            calleeConversation.ConferenceSession.BeginJoin(_conference.ConferenceUri, null /*joinOptions*/,
                EndJoinConference, calleeConversation.ConferenceSession);
            _waitForConferenceJoin.WaitOne();

            // Placing the calls on the conference-connected conversation 
            // connects to the respective MCUs. These calls may then be used to
            //communicate with the conference/MCUs.
            InstantMessagingCall instantMessagingCall2 = new InstantMessagingCall(calleeConversation);

            //Hooking up event handlers and then placing the call.
            instantMessagingCall2.InstantMessagingFlowConfigurationRequested +=
                this.instantMessagingCall2_InstantMessagingFlowConfigurationRequested;
            instantMessagingCall2.StateChanged += this._call_StateChanged;
            instantMessagingCall2.BeginEstablish(EndCallEstablish, instantMessagingCall2);

            //Synchronize to ensure that call has completed.
            _waitForCallEstablish.WaitOne();

            //Synchronize to ensure that all messages are sent and received
            _waitForMessageReceived.WaitOne();

            //Wait for shutdown initiated by user
            //_waitForShutdown.WaitOne();

            //UCMASampleHelper.PauseBeforeContinuing("Press ENTER to shutdown and exit.");

            return _conference;
        }
        catch (Exception ex)
        {
            WriteLog.AddLine("Cannot start conference: " + ex.Message);
            return null;
        }
    }

    #region side methods
    void ConferenceSession_StateChanged(object sender, StateChangedEventArgs<ConferenceSessionState> e)
    {
        ConferenceSession confSession = sender as ConferenceSession;

        //Session participants allow for disambiguation.
        WriteLog.AddLine("The conference session with Local Participant: " +
            confSession.Conversation.LocalParticipant + " has changed state. " +
            "The previous conference state was: " + e.PreviousState +
            " and the current state is: " + e.State);
    }

    // Flow created indicates that there is a flow present to begin media 
    // operations with, and that it is no longer null.
    public void instantMessagingCall_InstantMessagingFlowConfigurationRequested
        (object sender, InstantMessagingFlowConfigurationRequestedEventArgs e)
    {
        InstantMessagingFlow instantMessagingFlow = sender as InstantMessagingFlow;
        WriteLog.AddLine("Caller's Flow Created.");
        instantMessagingFlow = e.Flow;
        _IMFlow = instantMessagingFlow;

        // Now that the flow is non-null, bind the event handlers for State
        // Changed and Message Received. When the flow goes active, (as 
        // indicated by the state changed event) the program will send the 
        // IM in the event handler.
        instantMessagingFlow.StateChanged += this.instantMessagingFlow_StateChanged;

        // Message Received is the event used to indicate that a message has
        // been received from the far end.
        instantMessagingFlow.MessageReceived += this.instantMessagingFlow_MessageReceived;
    }

    // Flow created indicates that there is a flow present to begin media
    // operations with, and that it is no longer null.
    public void instantMessagingCall2_InstantMessagingFlowConfigurationRequested(
        object sender, InstantMessagingFlowConfigurationRequestedEventArgs e)
    {
        InstantMessagingFlow instantMessagingFlow = sender as InstantMessagingFlow;
        WriteLog.AddLine("Callee's Flow Created.");
        instantMessagingFlow = e.Flow;
        _IMFlow2 = instantMessagingFlow;

        // Now that the flow is non-null, bind the event handlers for State 
        // Changed and Message Received. When the flow goes active, the 
        // program will send the IM in the event handler.
        instantMessagingFlow.StateChanged += this.instantMessagingFlow2_StateChanged;

        // Message Received is the event used to indicate that a message 
        // from the far end has been received.
        instantMessagingFlow.MessageReceived += this.instantMessagingFlow2_MessageReceived;
    }

    private void instantMessagingFlow_StateChanged(object sender, MediaFlowStateChangedEventArgs e)
    {
        InstantMessagingFlow instantMessagingFlow = sender as InstantMessagingFlow;

        WriteLog.AddLine("Flow state changed from " + e.PreviousState + " to " + e.State);

        //When flow is active, media operations (here, sending an IM) may begin.
        if (e.State == MediaFlowState.Active)
        {
            _IMFlow = instantMessagingFlow;
            WriteLog.AddLine("Please type the message to send...");
            string msg = Console.ReadLine();
            //Send the message on the InstantMessagingFlow.
            instantMessagingFlow.BeginSendInstantMessage(msg, EndSendMessage, instantMessagingFlow);
        }
    }

    private void instantMessagingFlow2_StateChanged(object sender, MediaFlowStateChangedEventArgs e)
    {
        InstantMessagingFlow instantMessagingFlow = sender as InstantMessagingFlow;

        WriteLog.AddLine("Flow state changed from " + e.PreviousState + " to " + e.State);

        //When flow is active, media operations (here, sending an IM) may begin.
        if (e.State == MediaFlowState.Active)
        {
            _IMFlow2 = instantMessagingFlow;
        }
    }

    private void EndSendMessage(IAsyncResult ar)
    {
        InstantMessagingFlow instantMessagingFlow = ar.AsyncState as InstantMessagingFlow;
        try
        {
            instantMessagingFlow.EndSendInstantMessage(ar);
            WriteLog.AddLine("The message has been sent.");
        }
        catch (OperationTimeoutException opTimeEx)
        {
            // OperationFailureException: Indicates failure to connect the 
            // IM to the remote party due to timeout (called party failed 
            // to respond within the expected time).
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(opTimeEx.ToString());
        }
    }
    private void instantMessagingFlow_MessageReceived(object sender, InstantMessageReceivedEventArgs e)
    {
        InstantMessagingFlow instantMessagingFlow = sender as InstantMessagingFlow;
        //On an incoming Instant Message, print the contents to the console.
        WriteLog.AddLine("In caller's message handler: " + e.Sender.DisplayName + " said: " + e.TextBody);
        _waitForMessageReceived.Set();
    }

    private void instantMessagingFlow2_MessageReceived(object sender, InstantMessageReceivedEventArgs e)
    {
        InstantMessagingFlow instantMessagingFlow = sender as InstantMessagingFlow;
        //On an incoming Instant Message, print the contents to the console.
        WriteLog.AddLine("In callee's message handler: " + e.Sender.DisplayName + " said: " + e.TextBody);

        WriteLog.AddLine("Message received will be echoed");
        _messageToSend = "echo: " + e.TextBody;
        //Send the message on the InstantMessagingFlow.
        if (_IMFlow2 != null && _IMFlow2.State == MediaFlowState.Active)
        {
            _IMFlow2.BeginSendInstantMessage(_messageToSend, EndSendMessage, instantMessagingFlow);
        }
        else
            WriteLog.AddLine("Could not echo message because flow was either null or inactive");

        _waitForMessage2Received.Set();
    }

    private void EndCallEstablish(IAsyncResult ar)
    {
        Call call = ar.AsyncState as Call;
        try
        {
            call.EndEstablish(ar);
            WriteLog.AddLine("The call with Local Participant: " + call.Conversation.LocalParticipant +
                " and Remote Participant: " + call.RemoteEndpoint.Participant +
                " is now in the established state.");
        }
        catch (OperationFailureException opFailEx)
        {
            // OperationFailureException: Indicates failure to connect the 
            // call to the remote party.
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(opFailEx.ToString());
        }
        catch (RealTimeException exception)
        {
            // RealTimeException may be thrown on media or link-layer 
            //failures.
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(exception.ToString());
        }
        finally
        {
            //Again, just to sync the completion of the code.
            _waitForCallEstablish.Set();
        }
    }

    private void EndDeliverInvitation(IAsyncResult ar)
    {
        ConferenceInvitation invitation = ar.AsyncState as ConferenceInvitation;

        try
        {
            invitation.EndDeliver(ar);
        }
        catch (OperationFailureException opFailEx)
        {
            // OperationFailureException: Indicates failure to connect the 
            // call to the remote party.
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(opFailEx.ToString());
        }
        catch (RealTimeException exception)
        {
            // RealTimeException may be thrown on media or link-layer failures.
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(exception.ToString());
        }
        finally
        {
            //Again, just to sync the completion of the code.
            _waitForConversationInviteRemoteParticipants.Set();
        }
    }

    private void EndScheduleConference(IAsyncResult ar)
    {
        ConferenceServices confSession = ar.AsyncState as ConferenceServices;
        try
        {
            //End schedule conference returns the conference object, which 
            // contains the vast majority of the data relevant to that
            // conference.
            _conference = confSession.EndScheduleConference(ar);
            WriteLog.AddLine("");
            WriteLog.AddLine(" The conference is now scheduled.");
            WriteLog.AddLine("");

        }
        catch (ConferenceFailureException confFailEx)
        {
            // ConferenceFailureException may be thrown on failures to 
            // schedule due to MCUs being absent or unsupported, or due to
            // malformed parameters.
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(confFailEx.ToString());
        }

        //Again, for sync. reasons.
        _waitForConferenceScheduling.Set();
    }
    private void EndJoinConference(IAsyncResult ar)
    {
        ConferenceSession confSession = ar.AsyncState as ConferenceSession;
        try
        {
            confSession.EndJoin(ar);
        }
        catch (ConferenceFailureException confFailEx)
        {
            // ConferenceFailureException may be thrown on failures due to 
            // MCUs being absent or unsupported, or due to malformed parameters.
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(confFailEx.ToString());
        }
        catch (RealTimeException rTEx)
        {
            // TODO (Left to the reader): Add error handling code
            WriteLog.AddLine(rTEx.ToString());
        }
        finally
        {
            //Again, for sync. reasons.
            _waitForConferenceJoin.Set();
        }
    }

    //Just to record the state transitions in the console.
    void _call_StateChanged(object sender, CallStateChangedEventArgs e)
    {
        Call call = sender as Call;

        //Call participants allow for disambiguation.
        WriteLog.AddLine("The call with Local Participant: " + call.Conversation.LocalParticipant +
            " has changed state. The previous call state was: " + e.PreviousState +
            " and the current state is: " + e.State);
    }

    #endregion
}