コード例 #1
0
        /// <summary>
        /// Closes all outbound connections related to the current live agent client
        /// </summary>
        private void CloseClient(LiveSessionPublisher deadClient)
        {
            if (deadClient == null)
            {
                return;
            }

            //we are going to release every connection related to this client.  They might not all be - some might be local.
            var deadClientOptions = deadClient.GetOptions();

            if (deadClientOptions != null)
            {
                lock (m_DeadClients)
                {
                    //move everything to the dead collection and then we unregister that guy (this is what the iterators expect)
                    lock (m_ActiveClients)
                    {
                        foreach (var activeClient in m_ActiveClients)
                        {
                            if ((activeClient.GetOptions().Equals(deadClientOptions)) &&
                                (m_DeadClients.Contains(activeClient) == false))
                            {
                                m_DeadClients.Add(activeClient);
                            }
                        }
                    }

                    lock (m_PendingClients)
                    {
                        foreach (var pendingClient in m_PendingClients)
                        {
                            if ((pendingClient.GetOptions().Equals(deadClientOptions)) &&
                                (m_DeadClients.Contains(pendingClient) == false))
                            {
                                m_DeadClients.Add(pendingClient);
                            }
                        }
                        m_PendingClients.Clear();
                    }
                }

                //now we can kill them all
                DropDeadConnections();
            }

            deadClient.Dispose();
        }
コード例 #2
0
        private void DiscoveryFileMonitorOnFileChanged(object sender, LocalServerDiscoveryFileEventArgs e)
        {
            LiveSessionPublisher target;

            //this event *should* mean that we have a new proxy to connect to...
            lock (m_LocalProxyConnections)
            {
                if (!m_LocalProxyConnections.TryGetValue(e.File.FileNamePath, out target))
                {
                    if (e.File.IsAlive)
                    {
                        target = new LiveSessionPublisher(this, e.File);
                        target.Start();
                        m_LocalProxyConnections.Add(e.File.FileNamePath, target);
                    }
                }
            }
        }
コード例 #3
0
 /// <summary>
 /// Send the latest summary to the specified publisher
 /// </summary>
 private void SendSummary(LiveSessionPublisher publisher)
 {
     try
     {
         if (publisher.IsConnected)
         {
             publisher.SendSummary();
         }
     }
     catch (Exception ex)
     {
         if (!Log.SilentMode)
         {
             Log.Write(LogMessageSeverity.Error, LogWriteMode.Queued, ex, LogCategory,
                       "Failed to send summary to the server or other network proxy", "An exception was thrown that prevents us from sending the latest session summary to the server:\r\n" +
                       "Server or Proxy: {0}\r\n{1} Exception:\r\n{2}", publisher, ex.GetType(), ex.Message);
         }
     }
 }
コード例 #4
0
        /// <summary>
        /// Send the latest summary to the server
        /// </summary>
        public void SendSummary()
        {
            //We don't want to use locks so we need to do a point-in-time copy and then iterate through that copy.
            var client = m_Client;

            if (client != null)
            {
                SendSummary(client);
            }

            LiveSessionPublisher[] registeredClients;
            lock (m_LocalProxyConnections)
            {
                registeredClients = new LiveSessionPublisher[m_LocalProxyConnections.Count];
                m_LocalProxyConnections.Values.CopyTo(registeredClients, 0);
            }

            foreach (var liveSessionPublisher in registeredClients)
            {
                SendSummary(liveSessionPublisher);
            }
        }
コード例 #5
0
        /// <summary>
        /// Make sure we have an outbound proxy connection.
        /// </summary>
        /// <remarks>Intended for asynchronous execution from the thread pool.</remarks>
        private async Task AsyncEnsureRemoteConnection()
        {
            try
            {
                try
                {
                    DateTimeOffset hubConfigurationExpiration;
                    lock (m_HubConnection)
                    {
                        hubConfigurationExpiration = m_HubConfigurationExpiration;
                    }

                    NetworkConnectionOptions newLiveStreamOptions = null;
                    if ((m_HubConnection.IsConnected == false) || (hubConfigurationExpiration < DateTimeOffset.Now))
                    {
                        await m_HubConnection.Reconnect().ConfigureAwait(false);

                        DateTimeOffset connectionAttemptTime = DateTimeOffset.Now;

                        var status = await m_HubConnection.GetStatus().ConfigureAwait(false);

                        if (status.Status == HubStatus.Expired)
                        {
                            //if it's expired we're not going to check again for a while.
                            if (status.Repository?.ExpirationDt == null)
                            {
                                //should never happen, but treat as our long term case.
                                hubConfigurationExpiration = connectionAttemptTime.AddDays(1);
                            }
                            else
                            {
                                TimeSpan expiredTimeframe = connectionAttemptTime - status.Repository.ExpirationDt.Value;
                                if (expiredTimeframe.TotalHours < 24)
                                {
                                    hubConfigurationExpiration = connectionAttemptTime.AddMinutes(15); //we'll check pretty fast for that first day.
                                }
                                else if (expiredTimeframe.TotalDays < 4)
                                {
                                    hubConfigurationExpiration = connectionAttemptTime.AddHours(6);
                                }
                                else
                                {
                                    hubConfigurationExpiration = connectionAttemptTime.AddDays(1);
                                }
                            }

                            if (!Log.SilentMode)
                            {
                                Log.Write(LogMessageSeverity.Verbose, LogCategory, "Loupe server status is expired so no remote live view possible.", "Will check the server configuration again at {0}", hubConfigurationExpiration);
                            }
                        }
                        else
                        {
                            //we always want to periodically recheck the configuration in case it has changed anyway.
                            //we want to coordinate to an exact hour point to provide some consistency to worried users wondering when things will reconnect.
                            hubConfigurationExpiration = connectionAttemptTime.AddMinutes(60 - connectionAttemptTime.Minute); //so we go to a flush hour.
                            newLiveStreamOptions       = status.Repository?.AgentLiveStreamOptions;

                            if ((newLiveStreamOptions == null) && (!Log.SilentMode))
                            {
                                Log.Write(LogMessageSeverity.Information, LogCategory, "Remote live view not available due to server configuration", "The server is configured to have live view disabled so even though we have it enabled there is no live view.");
                            }
                        }

                        lock (m_HubConnection)
                        {
                            m_HubConfigurationExpiration = hubConfigurationExpiration;
                        }

                        //if we got different options then we're going to have to drop & recreate the client.
                        if (newLiveStreamOptions != m_ConnectionOptions)
                        {
                            if (!Log.SilentMode)
                            {
                                Log.Write(LogMessageSeverity.Verbose, LogCategory, "Loupe server live view options are different than our running configuration so we will close the client.", "New configuration:\r\n{0}", newLiveStreamOptions);
                            }
                            m_ConnectionOptions = newLiveStreamOptions;
                            CloseClient(m_Client);
                            m_Client = null;
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (!Log.SilentMode)
                    {
                        Log.Write(LogMessageSeverity.Warning, LogWriteMode.Queued, ex, LogCategory, "Remote viewer connection attempt failed",
                                  "While attempting to open our outbound connection to the proxy server an exception was thrown.  We will retry again later.\r\nException: {0}", ex.Message);
                    }
                }

                try
                {
                    if ((m_Client == null) && (m_ConnectionOptions != null))
                    {
                        LiveSessionPublisher newClient = new LiveSessionPublisher(this, m_ConnectionOptions);
                        newClient.Start();
                        m_Client = newClient;
                        SendSummary(m_Client); //since we just connected, we want to immediately tell it about us.
                    }
                }
                catch (Exception ex)
                {
                    if (!Log.SilentMode)
                    {
                        Log.Write(LogMessageSeverity.Warning, LogWriteMode.Queued, ex, LogCategory, "Remote viewer connection attempt failed",
                                  "While attempting to open our outbound connection to the proxy server an exception was thrown.  We will retry again later.\r\nException: {0}", ex.Message);
                    }
                }
            }
            finally
            {
                m_ActiveRemoteConnectionAttempt = false;
            }
        }
コード例 #6
0
        /// <summary>
        /// Inheritors should override this method to implement custom Close functionality
        /// </summary>
        /// <remarks>Code in this method is protected by a Queue Lock.
        /// This method is called with the Message Dispatch thread exclusively.</remarks>
        protected override void OnClose()
        {
            if (m_IsClosed)
            {
                return;
            }

            if (m_DiscoveryFileMonitor != null)
            {
                try
                {
                    m_DiscoveryFileMonitor.FileChanged -= DiscoveryFileMonitorOnFileChanged;
                    m_DiscoveryFileMonitor.FileDeleted -= DiscoveryFileMonitorOnFileDeleted;
                    m_DiscoveryFileMonitor.Stop();
                }
                catch
                {
                }
            }

            //move everything to the dead collection and then we unregister that guy (this is what the iterators expect)
            lock (m_DeadClients)
            {
                lock (m_ActiveClients)
                {
                    foreach (NetworkWriter activeClient in m_ActiveClients)
                    {
                        if (m_DeadClients.Contains(activeClient) == false)
                        {
                            m_DeadClients.Add(activeClient);
                        }
                    }
                    m_ActiveClients.Clear();
                    m_Buffer.Clear();
                }

                lock (m_PendingClients)
                {
                    foreach (NetworkWriter pendingClient in m_PendingClients)
                    {
                        if (m_DeadClients.Contains(pendingClient) == false)
                        {
                            m_DeadClients.Add(pendingClient);
                        }
                    }
                    m_PendingClients.Clear();
                }
            }

            //now we can kill them all
            DropDeadConnections();

            //Now ditch our local proxies.  We've already stopped the file monitor so new ones shouldn't be showing up.
            //Despite that we don't like holding locks if we don't have to.
            List <LiveSessionPublisher> registeredProxies = null;

            lock (m_LocalProxyConnections)
            {
                if (m_LocalProxyConnections.Count > 0)
                {
                    registeredProxies = new List <LiveSessionPublisher>(m_LocalProxyConnections.Values);
                    m_LocalProxyConnections.Clear();
                }
            }

            if (registeredProxies != null)
            {
                foreach (var localProxyConnection in registeredProxies)
                {
                    localProxyConnection.Close();
                }
            }

            if (m_Client != null)
            {
                m_Client.Dispose();
                m_Client = null;
            }

            if (m_HubConnection != null)
            {
                m_HubConnection.Dispose();
                m_HubConnection = null;
            }

            m_IsClosed = true;
        }