public static VidyoConversation CreateVideoConversation(VideoConversationInitializationParameters parameters)
        {
            using (Trace.Config.scope())
            {
                try
                {
                    // Initialize the conversation object
                    var conversation = new VidyoConversation
                    {
                        ScopedQueueName          = parameters.ScopedQueueName,
                        Room                     = VidyoServiceClient.CreateRoom(),
                        InitializationParameters = parameters
                    };

                    // Commit the conversation
                    Save(conversation);

                    return(conversation);
                }
                catch (Exception ex)
                {
                    Trace.WriteEventError(ex, "Error in CreateConversation: " + ex.Message, EventId.GenericError);
                    return(null);
                }
            }
        }
Exemplo n.º 2
0
        private void CicOnInteractionChanged(long interactionId, IDictionary <string, string> attributes)
        {
            using (Trace.Cic.scope())
            {
                try
                {
                    // Get conversation
                    var conversation = ConversationManager.GetConversation(interactionId);
                    if (conversation == null)
                    {
                        throw new ConversationNotFoundException(interactionId);
                    }

                    // Update attributes
                    conversation.UpdateAttributes(attributes);

                    // Action on hold
                    if (conversation.IsConversationMuted && !_cic.InteractionIsHeld(interactionId))
                    {
                        // Unmute
                        conversation.IsConversationMuted = false;
                        foreach (var participant in VidyoServiceClient.GetParticipants(conversation.Room.RoomId))
                        {
                            VidyoServiceClient.PerformAction(conversation.Room.RoomId, participant, RoomAction.MuteBoth,
                                                             false.ToString());
                        }
                    }
                    else if (!conversation.IsConversationMuted && _cic.InteractionIsHeld(interactionId))
                    {
                        // Mute
                        conversation.IsConversationMuted = true;
                        foreach (var participant in VidyoServiceClient.GetParticipants(conversation.Room.RoomId))
                        {
                            VidyoServiceClient.PerformAction(conversation.Room.RoomId, participant, RoomAction.MuteBoth,
                                                             true.ToString());
                        }
                    }
                }
                catch (ConversationNotFoundException ex)
                {
                    Trace.Cic.warning(ex.Message);
                }
                catch (Exception ex)
                {
                    Trace.WriteEventError(ex, "Error in CicOnInteractionChanged: " + ex.Message, EventId.GenericError);
                }
            }
        }
Exemplo n.º 3
0
 public void DoKickParticipant(object data)
 {
     using (Trace.Main.scope())
     {
         try
         {
             var participant = data as Participant;
             VidyoServiceClient.KickParticipant(VidyoRoomId, participant);
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex);
             Trace.Main.exception(ex, ex.Message);
         }
     }
 }
Exemplo n.º 4
0
 public void DoMuteVideo(object data)
 {
     using (Trace.Main.scope())
     {
         try
         {
             var parts = data as Tuple <Participant, bool>;
             VidyoServiceClient.MuteVideo(VidyoRoomId, parts.Item1, parts.Item2);
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex);
             Trace.Main.exception(ex, ex.Message);
         }
     }
 }
Exemplo n.º 5
0
        private bool CleanupConversation(VidyoConversation conversation)
        {
            using (Trace.Cic.scope())
            {
                // Delete room
                if (!VidyoServiceClient.DeleteRoom(conversation.Room.RoomId))
                {
                    Console.WriteLine("Error deleting room; deletion failed.");
                }

                // Cleanup conversation
                ConversationManager.RemoveConversation(conversation);

                return(true);
            }
        }
Exemplo n.º 6
0
        private void ParticipantCheckerTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            using (Trace.Main.scope())
            {
                try
                {
                    Context.Send(s => IsCheckingParticipants = true, null);

                    // Stop the timer so we can't back up on web service calls
                    _participantCheckerTimer.Stop();

                    //Console.WriteLine("Getting participants for room " + VidyoRoomId);

                    // Call web service to get participant list
                    var participants = VidyoServiceClient.GetParticipants(VidyoRoomId);
                    //Console.WriteLine("Participants (" + participants.Count + "): " + participants.Select(p => p.DisplayName).Aggregate((a, b) => a + "; " + b));

                    // Update list
                    Context.Send(s => Participants.AddRange(participants, true), null);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error getting participants: " + ex.Message);
                    Trace.Main.exception(ex);
                }
                finally
                {
                    Context.Send(s => IsCheckingParticipants = false, null);

                    // Only restart the timer if the interaction isn't disconnected
                    if (!_interaction.IsDisconnected)
                    {
                        _participantCheckerTimer.Start();
                    }
                }
            }
        }
Exemplo n.º 7
0
        private void ReconstituteConversations()
        {
            using (Trace.Cic.scope())
            {
                try
                {
                    // Load previous data
                    ConversationManager.LoadConversations();

                    // Check each conversation
                    var conversationsToDelete = new List <VidyoConversation>();
                    foreach (var conversation in ConversationManager.ConversationList)
                    {
                        using (Trace.Core.scope("Reconstitute " + conversation.ConversationId))
                        {
                            try
                            {
                                /* Store off the old interaction ID. This is necessary because of a race condition. When the old
                                 * interaction is disconnected, but not deallocated, the disconnected event will be raised when
                                 * the interaction reference is recreated and watches started. The disconnected event causes the
                                 * conversation object to be cleaned up, which deletes the Vidyo room. That's bad.
                                 *
                                 * This workaround clears the old conversation ID so that the conversation object won't be found
                                 * as a match when the disconnected event handler looks for a conversation by interaction ID. If
                                 * things are found to be in order, the interaction ID will be set back to the conversation.
                                 */
                                var oldInteractionId = conversation.InteractionId;
                                conversation.InteractionId = 0;
                                conversation.Save();


                                var needsInteraction = false;

                                // Does the interaction exist?
                                if (!_cic.InteractionExists(oldInteractionId))
                                {
                                    // No, but was the conversation waiting to be assigned?
                                    if (string.IsNullOrEmpty(conversation.UserOwner))
                                    {
                                        needsInteraction = true;
                                    }
                                    else
                                    {
                                        // It was assigned to a user, but are there people still in the room? (if yes, probably GI after switchover)
                                        if (VidyoServiceClient.GetParticipantCount(conversation.Room.RoomId).Count == 0)
                                        {
                                            throw new ConversationReconstitutionException(
                                                      "Interaction did not exist and nobody was in the Vidyo room.");
                                        }

                                        // People are in the room!
                                        Trace.Core.status(
                                            "Interaction {} did not exist, but participants exist in room {}. Creating new interaction.",
                                            oldInteractionId, conversation.Room.RoomId);

                                        // Need to make an interaction
                                        needsInteraction = true;
                                    }
                                }

                                // Interaction exists, validate it
                                if (_cic.InteractionIsDisconnected(oldInteractionId))
                                {
                                    // Was it waiting in queue and unassigned?
                                    if (string.IsNullOrEmpty(_cic.GetUserQueueName(oldInteractionId)))
                                    {
                                        // Yes. Need to make an interaction
                                        needsInteraction = true;
                                    }
                                    else
                                    {
                                        // Nope. Clean up (was assigned to user, but was disconnected while we weren't looking)
                                        throw new ConversationReconstitutionException("Interaction " +
                                                                                      oldInteractionId +
                                                                                      " is disconnected.");
                                    }
                                }

                                // Need to make a new interaction for the conversation?
                                if (needsInteraction)
                                {
                                    // Make a new interaction
                                    //TODO: How to handle chat after switchover? Does the interaction ID change?
                                    var interactionId = _cic.MakeInteraction(conversation.InitializationParameters);
                                    if (interactionId == 0)
                                    {
                                        throw new Exception("Failed to create new interaction!");
                                    }

                                    // Update conversation
                                    conversation.InteractionId = interactionId;
                                    conversation.UpdateAttributes(_cic.GetAttributes(interactionId,
                                                                                     conversation.AttributeDictionary.Select(kvp => kvp.Key).ToArray()));
                                    conversation.Save();

                                    // Done. Move on to next
                                    Trace.Core.status("Created new interaction {} for conversation", interactionId);
                                    continue;
                                }

                                // If we got here, everything is still in place
                                conversation.InteractionId = oldInteractionId;
                                conversation.Save();
                                Trace.Core.status("Conversation is still active");
                            }
                            catch (ConversationReconstitutionException ex)
                            {
                                Trace.Core.status("Marking conversation {} for cleanup. Reason: {}",
                                                  conversation.ConversationId, ex.Message);
                                conversationsToDelete.Add(conversation);
                            }
                            catch (Exception ex)
                            {
                                Trace.WriteEventError(ex,
                                                      "Failed to reconstitute conversation " + conversation.ConversationId + ". Message: " +
                                                      ex.Message, EventId.GenericError);
                                conversationsToDelete.Add(conversation);
                            }
                        }
                    }

                    // Remove inactive conversations
                    foreach (var conversation in conversationsToDelete)
                    {
                        CleanupConversation(conversation);
                    }
                }
                catch (Exception ex)
                {
                    Trace.WriteEventError(ex, "Error in ReconstituteConversations: " + ex.Message, EventId.GenericError);
                }
            }
        }