Timeout UCMA会议电话在第一次参与者建立时卡住
我正在尝试使用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”的首次意外异常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
类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
}