TVServer connection status (1 Viewer)

Stéphane Lenclud

Retired Team Member
  • Premium Supporter
  • April 29, 2013
    2,576
    1,294
    Home Country
    Germany Germany
    Is there a way to check the status of the TVServer? Is it online is it offline?
    I'm trying to fix MP1-4403.

    Calling "IsAnyCardRecording" the way MiniDisplay does it causes a 3 seconds lag when the server is offline.

    For some reason it's using this weird InvokeMethod stuff.
    Code:
    #region Copyright (C) 2005-2011 Team MediaPortal
    
    // Copyright (C) 2005-2011 Team MediaPortal
    // https://www.team-mediaportal.com
    //
    // MediaPortal is free software: you can redistribute it and/or modify
    // it under the terms of the GNU General Public License as published by
    // the Free Software Foundation, either version 2 of the License, or
    // (at your option) any later version.
    //
    // MediaPortal is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    // GNU General Public License for more details.
    //
    // You should have received a copy of the GNU General Public License
    // along with MediaPortal. If not, see <http://www.gnu.org/licenses/>.
    
    #endregion
    
    using System;
    using System.Collections;
    using System.Reflection;
    
    namespace MediaPortal.ProcessPlugins.MiniDisplayPlugin
    {
      public class DynaInvoke
      {
        public static Hashtable AssemblyReferences = new Hashtable();
        public static Hashtable ClassReferences = new Hashtable();
    
        public static DynaClassInfo GetClassReference(string AssemblyName, string ClassName)
        {
          Assembly assembly;
          if (ClassReferences.ContainsKey(AssemblyName))
          {
            return (DynaClassInfo)ClassReferences[AssemblyName];
          }
          if (!AssemblyReferences.ContainsKey(AssemblyName))
          {
            AssemblyReferences.Add(AssemblyName, assembly = Assembly.LoadFrom(AssemblyName));
          }
          else
          {
            assembly = (Assembly)AssemblyReferences[AssemblyName];
          }
          foreach (Type type in assembly.GetTypes())
          {
            if (type.IsClass && type.FullName.EndsWith("." + ClassName))
            {
              DynaClassInfo info = new DynaClassInfo(type, Activator.CreateInstance(type));
              ClassReferences.Add(AssemblyName, info);
              return info;
            }
          }
          throw new Exception("could not instantiate class");
        }
    
        public static object GetProperty(DynaClassInfo ci, string MethodName, object[] args)
        {
            return ci.type.InvokeMember(MethodName, BindingFlags.GetProperty, null, ci.ClassObject, args);
        }
    
        public static object GetProperty(string AssemblyName, string ClassName, string MethodName, object[] args)
        {
            return GetProperty(GetClassReference(AssemblyName, ClassName), MethodName, args);
        }
    
        public static object InvokeMethod(DynaClassInfo ci, string MethodName, object[] args)
        {
          return ci.type.InvokeMember(MethodName, BindingFlags.InvokeMethod, null, ci.ClassObject, args);
        }
    
        public static object InvokeMethod(string AssemblyName, string ClassName, string MethodName, object[] args)
        {
          return InvokeMethod(GetClassReference(AssemblyName, ClassName), MethodName, args);
        }
    
        public static object InvokeMethodSlow(string AssemblyName, string ClassName, string MethodName, object[] args)
        {
          foreach (Type type in Assembly.LoadFrom(AssemblyName).GetTypes())
          {
            if (type.IsClass && type.FullName.EndsWith("." + ClassName))
            {
              object target = Activator.CreateInstance(type);
              return type.InvokeMember(MethodName, BindingFlags.InvokeMethod, null, target, args);
            }
          }
          throw new Exception("could not invoke method");
        }
    
        public class DynaClassInfo
        {
          public object ClassObject;
          public Type type;
    
          public DynaClassInfo() {}
    
          public DynaClassInfo(Type t, object c)
          {
            this.type = t;
            this.ClassObject = c;
          }
        }
      }
    }

    Can any TVServer expert give me some insight?
     
    Last edited:

    Stéphane Lenclud

    Retired Team Member
  • Premium Supporter
  • April 29, 2013
    2,576
    1,294
    Home Country
    Germany Germany

    Stéphane Lenclud

    Retired Team Member
  • Premium Supporter
  • April 29, 2013
    2,576
    1,294
    Home Country
    Germany Germany
    That one also checks for an actual TCP connection which is potentially slow if the server is not there to respond and it needs to timeout.

    I'm not sure what you mean by "properly". That whole DynaInvoke thing in MiniDisplay does not seem proper.

    Could we have an actually dependency of MiniDisplayLibrary on TvControl? I'm not even sur how to implement it.

    Are the TvServer and RemoteControl class supposed to be supporting multiple client threads/processes?

    I'm seeing much static data in there and know to little about MP architecture and C# multithreading client/server stuff to be able to make proper judgement there.
     

    mm1352000

    Retired Team Member
  • Premium Supporter
  • September 1, 2008
    21,578
    8,227
    Home Country
    New Zealand New Zealand
    That one also checks for an actual TCP connection which is potentially slow if the server is not there to respond and it needs to timeout.
    Timeout on the attempt is set to MAX_TCP_TIMEOUT = 1000 ms = 1 second. Is that really too long for you?

    I'm not sure what you mean by "properly". That whole DynaInvoke thing in MiniDisplay does not seem proper.
    Where did I say "properly"? :confused:

    Could we have an actually dependency of MiniDisplayLibrary on TvControl? I'm not even sur how to implement it.
    IMO bad idea, because what if the implementation in TvControl changes (like it has for TVE 3.5)?

    Are the TvServer and RemoteControl class supposed to be supporting multiple client threads/processes?
    Both of those classes run on the client side. They don't have to support multiple clients. No, they probably don't support multi-threading... but then they shouldn't don't really need to.

    I'm seeing much static data in there and know to little about MP architecture and C# multithreading client/server stuff to be able to make proper judgement there.
    Static is used because there should only be one connection per client.
     

    Stéphane Lenclud

    Retired Team Member
  • Premium Supporter
  • April 29, 2013
    2,576
    1,294
    Home Country
    Germany Germany
    That's exactly what I thought, we have a single local client architecture that's being abused by MiniDisplay so my changes should not make it worst than it already is. If anything it should be better since it limits somewhat the number of request to the server.

    Does 3.5 have a multiclient architecture?

    Is there a proper way for me to get recording and TV view status from MiniDisplay without abusing our TvControl?
     

    mm1352000

    Retired Team Member
  • Premium Supporter
  • September 1, 2008
    21,578
    8,227
    Home Country
    New Zealand New Zealand
    abused by MiniDisplay
    Why abused?

    If anything it should be better since it limits somewhat the number of request to the server.
    You seem to be assuming that some other process will always be running to ensure that _isRemotingConnected has the correct/true value. IMO that assumption is not necessarily correct. That is why I think you should use RemoteControl.Instance.* (like the TV plugin, MP configuration etc.) if you actually need to get information from the server. If the server is not present then yes you will have the timeout delay... but if you're worried about timeouts, simply don't make the call from threads that you don't want to be blocked. Minidisplay should have its own background thread for updating the recording and timeshifting status. It should definitely not do it in the UI thread, because that would block rendering the MP UI (!!!).
     

    Users who are viewing this thread

    Top Bottom