UCMA电话会议卡在第一位参与者建立

时间:2015-07-15 06:12:36

标签: timeout call lync ucma conference

我正在尝试使用UCMA 4.0基本会议示例和第一个用户端点在建立呼叫时停止会议(它的lync没有振铃)。一段时间后会触发超时异常。主要问题是什么?

BTW,平台正在启动,发现已建立3个应用程序端点。

  

SIP:kl.dev.local@dev.local; GRUU;不透明= SRVR:yyapp:EHghH8UXNVqIedXU3YgJyQAAYYApp   SIP:kl.cdev.local@dev.local; GRUU;不透明= SRVR:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine1   SIP:kl.dev.local@dev.local; GRUU;不透明= SRVR:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine2   SIP:kl.dev.local@dev.local; GRUU;不透明= SRVR:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine3   'LyncGame.Gateway.TestConnection.vshost.exe'(CLR v4.0.30319:LyncGame.Gateway.TestConnection.vshost.exe):已加载'C:\ Windows \ Microsoft.Net \ assembly \ GAC_MSIL \ System.Data.SqlXml \ v4 .0_4.0.0.0__b77a5c561934e089 \ System.Data.SqlXml.dll”。跳过加载符号。模块已经过优化,调试器选项“Just My Code”已启用。   '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)。   'LyncGame.Gateway.TestConnection.vshost.exe'(CLR v4.0.30319:LyncGame.Gateway.TestConnection.vshost.exe):已加载'C:\ Windows \ Microsoft.Net \ assembly \ GAC_MSIL \ System.Security \ v4.0_4 .0.0.0__b03f5f7f11d50a3a \ System.Security.dll”。跳过加载符号。模块已经过优化,调试器选项“Just My Code”已启用。   线程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”类型的第一次机会异常

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
}

}

1 个答案:

答案 0 :(得分:0)

这里真正有用的另一件事是在应用程序服务器上运行OCSLogger并查看返回的内容。您可以运行S4以获取SIP跟踪。可能只是像你一样简单,无法在5061(或你在配置中指定的任何回调端口)上接收消息。如果它只在A / V上失败,请查看SDP提供/回答中正在使用的地址,并查看这些地址是否也可以访问。同样,OCSLogger(或Lync CLS)和Snooper也是您的朋友。