private void EstablishCall() { // Create a new Conversation. Conversation conversation = new Conversation(_appEndpoint); // Create a new IM call. _imCall = new InstantMessagingCall(conversation); try { // Establish the IM call. _imCall.BeginEstablish(_destinationSipUri, new CallEstablishOptions(), result => { try { // Finish the asynchronous operation. _imCall.EndEstablish(result); } catch (RealTimeException ex) { // Catch and log exceptions. _logger.Log("Failed establishing IM call", ex); } }, null ); } catch (InvalidOperationException ioex) { _logger.Log("Failed establishing IM call", ioex); } }
//Launches an instant message. Text of the message depends on the parameter value. public void UcmaIM(Int32 choice) { helper = new UCMASampleHelper(); userEndpoint = helper.CreateEstablishedUserEndpoint("SampleUser"); Console.WriteLine("endpoint owned by " + userEndpoint.OwnerUri + " is established/registered"); ConversationSettings conversationSettings = new ConversationSettings(); conversationSettings.Subject = conversationSubject; Conversation conversation = new Conversation(userEndpoint, conversationSettings); ImCall = new InstantMessagingCall(conversation); ImCall.InstantMessagingFlowConfigurationRequested += new EventHandler <InstantMessagingFlowConfigurationRequestedEventArgs>(ImCall_InstantMessagingFlowConfigurationRequested); Int32 helloChoice = 1; Int32 goodbyeChoice = 2; if (choice == helloChoice) { messageText = "hello"; } else if (choice == goodbyeChoice) { messageText = "goodbye"; } else { messageText = "press 1 or press 2"; } string targetURI = ConfigurationManager.AppSettings["UserURI1"]; ImCall.BeginEstablish(targetURI, null, CallEstablishCompleted, null); completedEvent.WaitOne(); }
private void Run() { // A helper class to take care of platform and endpoint setup and // cleanup. This has been abstracted from this sample to focus on // Call Control. _helper = new UCMASampleHelper(); // Create a user endpoint, using the network credential object // defined above. UserEndpoint callerEndpoint = _helper.CreateEstablishedUserEndpoint( "Caller" /*endpointFriendlyName*/); // Create a second user endpoint, using the network credential object // defined above. UserEndpoint calleeEndpoint = _helper.CreateEstablishedUserEndpoint( "Callee" /*endpointFriendlyName*/); // Here, we are accepting an Instant Messaging call only. If the // incoming call is not an Instant Messaging call (for example, an // AudioVideo call or a custom Call, then it will not get raised to // the application. UCMA 3.0 handles this silently by having the call // types register for various modalities (as part of the extensibility // framework). The appropriate action (here, accepting the call) will // be handled in the handler assigned to the method call below. calleeEndpoint.RegisterForIncomingCall <InstantMessagingCall>(On_InstantMessagingCall_Received); // Setup the call and conversation objects for the initial call (IM) // and place the call (synchronously). _conversation = new Conversation(callerEndpoint); InstantMessagingCall instantMessagingCall = new InstantMessagingCall(_conversation); // Add registration for the AudioVideo modality, before placing the // second call. This could have been done at any time before placing // the audio video call. This handler could choose to accept, deflect // or drop this portion of the call entirely. calleeEndpoint.RegisterForIncomingCall <AudioVideoCall>(On_AudioVideoCall_Received); // Place the call to the remote party, without specifying any custom // options. instantMessagingCall.BeginEstablish(calleeEndpoint.OwnerUri, new ToastMessage("Sample Toast Message"), null, CallEstablishCompleted, instantMessagingCall); // Force synchronization to ensure that the both AVCall and IMCall // are now complete. _sampleCompleted.WaitOne(); UCMASampleHelper.PauseBeforeContinuing("Press ENTER to shutdown and exit."); //And shutdown (synchronously). Console.WriteLine("Shutting down the sample..."); _helper.ShutdownPlatform(); }
/// <summary> /// Overridden process method. /// </summary> public override void Process() { bool exceptionEncountered = true; Exception exceptionCaught = null; try { CallEstablishOptions establishOptions = new CallEstablishOptions(); //Add custom MIME parts based on conversation context. if (m_cutomMimePart != null) { establishOptions.CustomMimeParts.Add(m_cutomMimePart); } //Construct the destination uri, if needed. m_imCall.BeginEstablish(m_destinationUri, establishOptions, this.InstantMessagingCallEstablishCompleted, null /*state*/); exceptionEncountered = false; } catch (ArgumentException ae) { Helper.Logger.Error("Exception = {0}", EventLogger.ToString(ae)); exceptionCaught = ae; } catch (InvalidOperationException ioe) { Helper.Logger.Info("Exception = {0}", EventLogger.ToString(ioe)); exceptionCaught = ioe; } finally { if (exceptionEncountered) { OperationFault operationFault = null; if (exceptionCaught != null) { operationFault = FaultHelper.CreateClientOperationFault(exceptionCaught.Message, exceptionCaught.InnerException); } else { operationFault = FaultHelper.CreateServerOperationFault(FailureStrings.GenericFailures.UnexpectedException, null /*innerException*/); } this.CompleteEstablishOperationWithException(new FaultException <OperationFault>(operationFault)); } } }
public void EstablishInstantMessagingCall(Conversation conversation) { if (_state == TranscriptRecorderState.Terminated) { NonBlockingConsole.WriteLine("Error: IMTranscriptRecorder is shutdown."); // TODO: error message return; } if (_instantMessagingCall != null) { NonBlockingConsole.WriteLine("Warn: IMCall already exists for this Conversation. Shutting down previous call..."); // TODO: Info message TerminateCall(); } _state = TranscriptRecorderState.Initialized; this._waitForIMCallTerminated.Reset(); try { InstantMessagingCall imCall = new InstantMessagingCall(conversation); // Register for Call events _instantMessagingCall = imCall; // Call: StateChanged: Only hooked up for logging, to show the call // state transitions. _instantMessagingCall.StateChanged += new EventHandler <CallStateChangedEventArgs>(InstantMessagingCall_StateChanged); _instantMessagingCall.InstantMessagingFlowConfigurationRequested += new EventHandler <InstantMessagingFlowConfigurationRequestedEventArgs>(InstantMessagingCall_FlowConfigurationRequested); // Establish AudioVideoCall imCall.BeginEstablish(IMCall_EstablishCompleted, imCall); } catch (InvalidOperationException ex) { NonBlockingConsole.WriteLine("Error: imCall.BeginEstablish failed. Exception: {0}", ex.ToString()); // TODO: Error Message } }
private void EstablishCall() { // Create a new Conversation. Conversation conversation = new Conversation(_appEndpoint); // Create a new IM call. _imCall = new InstantMessagingCall(conversation); try { // Establish the IM call. _imCall.BeginEstablish(_destinationSipUri, new CallEstablishOptions(), result => { try { // Finish the asynchronous operation. _imCall.EndEstablish(result); _imCall.Flow.MessageReceived += new EventHandler<InstantMessageReceivedEventArgs>(OnMessageReceived); SendMessage("Jackdaws love my big sphinx of quartz."); } catch (RealTimeException ex) { // Catch and log exceptions. _logger.Log("Failed establishing IM call", ex); } }, null ); } catch (InvalidOperationException ioex) { _logger.Log("Failed establishing IM call", ioex); } }
private void Run() { // A helper class to take care of platform and endpoint setup and // cleanup. This has been abstracted from this sample to focus on // Call Control. _helper = new UCMASampleHelper(); // Create a user endpoint, using the network credential object // defined above. UserEndpoint callerEndpoint = _helper.CreateEstablishedUserEndpoint("Caller" /*endpointFriendlyName*/); // Create a second user endpoint, using the network credential object // defined above. UserEndpoint calleeEndpoint = _helper.CreateEstablishedUserEndpoint("Callee" /*endpointFriendlyName*/); // Here, we are accepting an InstantMessaging call only. // If the incoming call is not an InstantMessaging call (for example, // an AudioVideo call) then it will not get raised to the application. // UCMA 3.0 handles this silently by having the call types register // for various modalities (as part of the extensibility framework). // The appropriate action (here, accepting the call) will be handled // in the handler assigned to the method call below. calleeEndpoint.RegisterForIncomingCall <InstantMessagingCall> (On_InstantMessagingCall_Received_ByCallee); // Setup the call and conversation objects for the initial call (IM) // and place the call (synchronously). Conversation callerConversation = new Conversation(callerEndpoint); InstantMessagingCall callerInstantMessagingCall = new InstantMessagingCall(callerConversation); callerInstantMessagingCall.BeginEstablish(calleeEndpoint.OwnerUri, null, EndCallerCallEstablish, callerInstantMessagingCall); // Force synchronization to ensure that the call is now complete. _waitForCallAcceptByCallee.WaitOne(); _waitForCallerCallEstablish.WaitOne(); // Now that the call is established, we can begin the escalation. // First, we bind the conference state changed event handler, largely // for logging reasons. callerConversation.ConferenceSession.StateChanged += new EventHandler <StateChangedEventArgs <ConferenceSessionState> >(ConferenceSession_StateChanged); Console.WriteLine(""); Console.WriteLine(" Beginning conference creation and escalation..."); Console.WriteLine(""); // Next, the initiator of the escalation creates an ad-hoc conference // (using the current modalities present in the conversation) by calling // ConferenceSession.BeginJoin on a conversation, without providing // a conference URI. This prepares the calls for actual escalation by // binding the appropriate conference multipoint Control Unit (MCU) // sessions. When EndJoinConference is called, it will kick off the // subsequent escalation. As part of the escalation, the remote party // will receive an escalation request, via the event on the far end // conversation, EscalateToConferenceRequested. Also, the existing // calls will be shifted to the MCUs. callerConversation.ConferenceSession.BeginJoin(default(ConferenceJoinOptions), EndCallerJoinConference, callerConversation.ConferenceSession); //Wait for both sides to fully escalate to the new conference. _waitForCallerConferenceEscalation.WaitOne(); _waitForCalleeConferenceEscalation.WaitOne(); Console.WriteLine(""); Console.WriteLine(" Beginning conference command and control..."); Console.WriteLine(""); // Promote a participant to leader; Leaders can lock and unlock the // conference, as well as possessing the ability to eject and control // other participants, and mute participants (in an Audio conference). // For purposes of the demonstration, choose an arbitrary conference // participant here, the first. ConversationParticipant target = null; if (callerConversation.RemoteParticipants.Count >= 1) { target = callerConversation.RemoteParticipants[0]; } else { // TODO (Left to the reader): Add error handling code. } Console.WriteLine("User " + target.UserAtHost + " is currently an " + target.Role + "."); // Note: This is the naive synch implementation, and is not generally // suitable for production code. It is only used here for brevity. callerConversation.ConferenceSession.BeginModifyRole(target, ConferencingRole.Leader, EndModifyRole, callerConversation.ConferenceSession); _waitForRoleModification.WaitOne(); Console.WriteLine("User " + target.UserAtHost + " is now a " + target.Role + "."); Console.WriteLine("The conference access level is currently " + callerConversation.ConferenceSession.AccessLevel + "."); // Locking the conference prevents new users from joining the // conference, unless explicitly called into the conference through // the dialout API. callerConversation.ConferenceSession.BeginLockConference(EndLockConference, callerConversation.ConferenceSession); _waitForConferenceLock.WaitOne(); Console.WriteLine("The conference accesslevel is now " + callerConversation.ConferenceSession.AccessLevel + "."); // Now, eject the participant, and then shut down the platform. Console.WriteLine("The conference currently has " + callerConversation.ConferenceSession.GetRemoteParticipantEndpoints().Count + " attendees."); // Ejection can only be performed by leaders of the conference. callerConversation.ConferenceSession.BeginEject(target, EndEject, callerConversation.ConferenceSession); _waitForParticipantEject.WaitOne(); Console.WriteLine("The conference now has " + callerConversation.ConferenceSession.GetRemoteParticipantEndpoints().Count + " attendees."); _helper.ShutdownPlatform(); Console.ReadLine(); }
private void Run() { // A helper class to take care of platform and endpoint setup and // cleanup. This has been abstracted from this sample to focus on // Call Control. _helper = new UCMASampleHelper(); // Create a user endpoint, using the network credential object // defined above. _callerEndpoint = _helper.CreateEstablishedUserEndpoint( "Conference Leader" /* friendly name for conference leader endpoint */); // Create a second user endpoint, using the network credential object // defined above. _calleeEndpoint = _helper.CreateEstablishedUserEndpoint( "Conference Attendee" /* friendly name for conference attendee endpoint */); // Get the URI for the user logged onto Microsoft Lync String _ocUserURI = "sip:" + UCMASampleHelper.PromptUser( "Enter the URI for the user logged onto Microsoft Lync, in the User@Host format => ", "RemoteUserURI" /* key to specify remote user's URI in app.config */); // 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 = "Interesting Description"; // 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 my conference"); 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."); }
private void Run() { // Initialize and startup the platform. Exception ex = null; try { // Create the UserEndpoint _helper = new UCMASampleHelper(); _userEndpoint = _helper.CreateEstablishedUserEndpoint( "IMCall Sample User" /*endpointFriendlyName*/); Console.Write("The User Endpoint owned by URI: "); Console.Write(_userEndpoint.OwnerUri); Console.WriteLine(" is now established and registered."); // Setup the conversation and place the call. ConversationSettings convSettings = new ConversationSettings(); convSettings.Priority = _conversationPriority; convSettings.Subject = _conversationSubject; // Conversation represents a collection of modes of communication // (media types)in the context of a dialog with one or multiple // callees. Conversation conversation = new Conversation(_userEndpoint, convSettings); _instantMessagingCall = new InstantMessagingCall(conversation); // Call: StateChanged: Only hooked up for logging. Generally, // this can be used to surface changes in Call state to the UI _instantMessagingCall.StateChanged += this.InstantMessagingCall_StateChanged; // Subscribe for the flow created event; the flow will be used to // send the media (here, IM). // Ultimately, as a part of the callback, the messages will be // sent/received. _instantMessagingCall.InstantMessagingFlowConfigurationRequested += this.InstantMessagingCall_FlowConfigurationRequested; // Get the sip address of the far end user to communicate with. String _calledParty = "sip:" + UCMASampleHelper.PromptUser( "Enter the URI of the user logged onto Microsoft Lync, in the User@Host format => ", "RemoteUserURI"); // Place the call to the remote party, without specifying any // custom options. Please note that the conversation subject // overrides the toast message, so if you want to see the toast // message, please set the conversation subject to null. _instantMessagingCall.BeginEstablish(_calledParty, new ToastMessage("Hello Toast"), null, CallEstablishCompleted, _instantMessagingCall); } catch (InvalidOperationException iOpEx) { // Invalid Operation Exception may be thrown if the data provided // to the BeginXXX methods was invalid/malformed. // TODO (Left to the reader): Write actual handling code here. ex = iOpEx; } finally { if (ex != null) { // If the action threw an exception, terminate the sample, // and print the exception to the console. // TODO (Left to the reader): Write actual handling code here. Console.WriteLine(ex.ToString()); Console.WriteLine("Shutting down platform due to error"); _helper.ShutdownPlatform(); } } // Wait for sample to complete _sampleCompletedEvent.WaitOne(); }
public void EstablishInstantMessagingCall(Conversation conversation) { if (_state == TranscriptRecorderState.Terminated) { NonBlockingConsole.WriteLine("Error: IMTranscriptRecorder is shutdown."); // TODO: error message return; } if (_instantMessagingCall != null) { NonBlockingConsole.WriteLine("Warn: IMCall already exists for this Conversation. Shutting down previous call..."); // TODO: Info message TerminateCall(); } _state = TranscriptRecorderState.Initialized; this._waitForIMCallTerminated.Reset(); try { InstantMessagingCall imCall = new InstantMessagingCall(conversation); // Register for Call events _instantMessagingCall = imCall; // Call: StateChanged: Only hooked up for logging, to show the call // state transitions. _instantMessagingCall.StateChanged += new EventHandler<CallStateChangedEventArgs>(InstantMessagingCall_StateChanged); _instantMessagingCall.InstantMessagingFlowConfigurationRequested += new EventHandler<InstantMessagingFlowConfigurationRequestedEventArgs>(InstantMessagingCall_FlowConfigurationRequested); // Establish AudioVideoCall imCall.BeginEstablish(IMCall_EstablishCompleted, imCall); } catch (InvalidOperationException ex) { NonBlockingConsole.WriteLine("Error: imCall.BeginEstablish failed. Exception: {0}", ex.ToString()); // TODO: Error Message } }