2

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

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

sip:kl.dev.local@dev.local;gruu;opaque=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAYYApp sip:kl.cdev.local@dev.local;gruu;opaque=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine1 sip:kl.dev.local@ dev.local;gruu;opaque=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine2 sip:kl.dev.local@dev.local;gruu;opaque=srvr:yyapp:EHghH8UXNVqIedXU3YgJyQAAMachine3 'LyncGame.Gateway.TestConnection.vshost.exe' (CLR v4.0.30 :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”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。“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'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。线程 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”类型的第一次机会异常 线程 0x2214 已退出,代码为 259 (0x103)。线程 0x1564 已退出,代码为 259 (0x103)。线程 0x3740 已退出,代码为 259 (0x103)。线程 0x28a8 已退出,代码为 259 (0x103)。线程 0x1da8 已退出,代码为 259 (0x103)。Microsoft.Rtc.Collaboration.dll 中出现了“Microsoft.Rtc.Signaling.OperationTimeoutException”类型的第一次机会异常 线程 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
}

}

4

1 回答 1

0

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

于 2015-07-17T21:31:31.107 回答