예제 #1
0
        /// <summary>
        /// Registers the given bound service into this service manager
        /// </summary>
        /// <param name="service">The bound service to register</param>
        /// <returns>The boundID of this service</returns>
        public int BoundService(BoundService service)
        {
            lock (this.mBoundServices)
            {
                int boundID = this.mNextBoundID++;

                // add the service to the bound services map
                this.mBoundServices[boundID] = service;

                return boundID;
            }
        }
예제 #2
0
        /// <summary>
        /// Binds a new object of this type with the given objectData to provide a stateful
        /// interface to itself
        ///
        /// WARNING: Some MachoBindObject calls also include a call to a method inside the new stateful
        /// service, this also handles that behaviour
        /// </summary>
        /// <param name="objectData">The information of the object to be stateful about</param>
        /// <param name="callInfo">The information on the call</param>
        /// <param name="call">The call object with extra information</param>
        /// <returns></returns>
        protected PyDataType MachoBindObject(PyDataType objectData, PyDataType callInfo, CallInformation call)
        {
            // create the bound instance and register it in the bound services
            BoundService instance = this.CreateBoundInstance(objectData, call);

            // bind the service
            int boundID = this.BoundServiceManager.BoundService(instance);
            // build the bound service string
            string boundServiceStr = this.BoundServiceManager.BuildBoundServiceString(boundID);

            // TODO: the expiration time is 1 day, might be better to properly support this?
            // TODO: investigate these a bit more closely in the future
            // TODO: i'm not so sure about the expiration time
            PyTuple boundServiceInformation = new PyTuple(new PyDataType[]
            {
                boundServiceStr, DateTime.UtcNow.Add(TimeSpan.FromDays(1)).ToFileTime()
            });

            // after the service is bound the call can be run (if required)
            PyTuple result = new PyTuple(2);

            result[0] = new PySubStruct(new PySubStream(boundServiceInformation));

            if (callInfo is PyNone)
            {
                result[1] = null;
            }
            else
            {
                PyTuple      data           = callInfo as PyTuple;
                string       func           = data[0] as PyString;
                PyTuple      arguments      = data[1] as PyTuple;
                PyDictionary namedArguments = data[2] as PyDictionary;

                CallInformation callInformation = new CallInformation
                {
                    Client       = call.Client,
                    NamedPayload = namedArguments,
                    CallID       = call.CallID,
                    From         = call.From,
                    PacketType   = call.PacketType,
                    Service      = null,
                    To           = call.To
                };

                result[1] = this.BoundServiceManager.ServiceCall(boundID, func, arguments, callInformation);
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Takes the given payload and searches in this service manager for the best service match to call the given method
        /// if possible
        /// </summary>
        /// <param name="boundID">The boundID to call at</param>
        /// <param name="call">The method to call</param>
        /// <param name="payload">Parameters for the method</param>
        /// <param name="callInformation">Any extra information for the method call</param>
        /// <returns>The result of the call</returns>
        /// <exception cref="ServiceDoesNotExistsException">If the boundID doesn't match any registered bound service</exception>
        /// <exception cref="ServiceDoesNotContainCallException">If the service was found but no matching call was found</exception>
        public PyDataType ServiceCall(int boundID, string call, PyTuple payload, CallInformation callInformation)
        {
            // relay the exception throw by the call
            try
            {
                BoundService serviceInstance = this.mBoundServices[boundID];
         
                Log.Trace($"Calling {serviceInstance.GetType().Name}::{call} on bound service {boundID}");
            
                if(serviceInstance is null)
                    throw new ServiceDoesNotExistsException($"Bound Service {boundID}");

                List<MethodInfo> methods = this.FindMethods(serviceInstance, $"(boundID {boundID}) {serviceInstance.GetType().Name}", call);

                if (FindSuitableMethod(methods, payload, callInformation, out object[] invokeParameters, out MethodInfo method) == false)