Exemple #1
0
        /// <summary>
        /// Creates the proxy.
        /// </summary>
        /// <returns>Contract</returns>
        public TContract CreateProxy()
        {
            ConstructorInfo         c     = mRealProxyType.GetConstructor(new Type[] { typeof(Channel), typeof(String) });
            ProxyBase               proxy = (ProxyBase)c.Invoke(new object[] { mChannel, mChannel.Connect(mRemoteEndPoint) });
            WellKnownObjectModeEnum mode  = WellKnownObjectModeEnum.PerSession;

            if (ContractValidator.GetWellKnownObjectMode(mContractInterface, out mode) && mode == WellKnownObjectModeEnum.PerSession)
            {
                ServiceBase.RegisterProxy(mChannel, mContractInterface, proxy.GetType(), proxy.SessionId, proxy.ProxyId, proxy);
            }
            return((TContract)(IRemoteContract)proxy);
        }
        /// <summary>
        /// Check integrity of the provided proxy implementation
        /// </summary>
        /// <param name="implClass">The impl class.</param>
        /// <exception cref="InvalidProxyImplementationException">
        /// </exception>
        public static void ValidateProxyIntegration(Type implClass)
        {
            if (implClass == null)
            {
                ThrowHelper.ThrowArgumentNullException("implClass");
            }

            // Szabályok
            // 1, az implementációnak ki kell terjesztenie legalább egy vagy több contract-ot
            // 2, több kiterjesztett contract esetén, a contract-oknak azonos WellKnownObjectMode-ra kell lennie állítva
            // 3, az osztálynak példányosíthatónak kell lennie:
            //    a, nem lehet abstract, interface vagy enum
            //    b, A ProxyBase-ből kell származnia a megfelelő public constructor-al (Channel, String)

            // 3a. szabály ellenőrzése
            if (implClass.IsEnum || implClass.IsAbstract || implClass.IsInterface)
            {
                throw new InvalidProxyImplementationException(String.Format("Invalid proxy type: '{0}'. Proxy must be an instantiable class.", implClass.FullName));
            }

            // 2. szabály ellenőrzése
            bool foundFlag = false;
            WellKnownObjectModeEnum referenceMode = WellKnownObjectModeEnum.PerSession;

            CheckObjectMode(implClass, ref referenceMode, ref foundFlag);

            // 1. szabály ellenőrzése
            if (!foundFlag)
            {
                // ha ugyanis nem talált egy WellKnownObjectMode értéket sem az öröklési láncban, akkor ott nincs vagy hibás a contract definíció
                throw new InvalidProxyImplementationException(String.Format("Valid contract definition has not found on proxy type: {0}", implClass.FullName));
            }

            // 3b. szabály ellenőrzése
            if (!typeof(ProxyBase).IsAssignableFrom(implClass))
            {
                throw new InvalidProxyImplementationException(String.Format("Proxy '{0}' must be inherited from '{2}'.", implClass.FullName, typeof(ProxyBase).FullName));
            }

            // 3b. szabály ellenőrzése
            try
            {
                ConstructorInfo c = implClass.GetConstructor(new Type[] { typeof(Channel), typeof(String) });
                if (!c.IsPublic)
                {
                    throw new InvalidProxyImplementationException(String.Format("Required constructor with type parameters ({0}, {1}) must be public on proxy type '{2}'.", typeof(Channel).FullName, typeof(String).FullName, implClass.FullName));
                }
            }
            catch (Exception ex)
            {
                throw new InvalidProxyImplementationException(String.Format("Required constructor with type parameters ({0}, {1}) has not found on proxy type '{2}'.", typeof(Channel).FullName, typeof(String).FullName, implClass.FullName), ex);
            }
        }
 private static void CheckObjectMode(Type type, ref WellKnownObjectModeEnum targetMode, ref bool foundFlag)
 {
     if (type.GetInterfaces().Length > 0)
     {
         foreach (Type interfaceClass in type.GetInterfaces())
         {
             ServiceContractAttribute scAnnotation = TypeHelper.GetAttribute <ServiceContractAttribute>(interfaceClass);
             if (scAnnotation != null)
             {
                 // van attribútum
                 if (!foundFlag)
                 {
                     // meg van az első WellKnownObjectMode, ez lesz a referencia a többi számára
                     targetMode = scAnnotation.WellKnownObjectMode;
                     foundFlag  = true;
                 }
                 else if (!targetMode.Equals(scAnnotation.WellKnownObjectMode))
                 {
                     // eltérő
                     throw new InvalidProxyImplementationException(String.Format("Different {0} definitions found on type '{1}'. Contract '{2}' configured to '{3}' and previously found '{4}' mode.", typeof(WellKnownObjectModeEnum).FullName, type.FullName, interfaceClass.FullName, scAnnotation.WellKnownObjectMode, targetMode.ToString()));
                 }
             }
             if (!foundFlag)
             {
                 // még nincs referencia WellKnownObjectMode
                 CheckObjectMode(interfaceClass, ref targetMode, ref foundFlag);
             }
             else
             {
                 // már van
                 WellKnownObjectModeEnum interfaceMode = WellKnownObjectModeEnum.PerSession;
                 bool tempFound = false;
                 CheckObjectMode(interfaceClass, ref interfaceMode, ref tempFound);
                 if (tempFound && foundFlag && !targetMode.Equals(interfaceMode))
                 {
                     // eltérő
                     throw new InvalidProxyImplementationException(String.Format("Different {0} definitions found on type '{1}'. Contract '{2}' configured to '{3}' and previously found '{4}' mode.", typeof(WellKnownObjectModeEnum).FullName, type.FullName, interfaceClass.FullName, interfaceMode.ToString(), targetMode.ToString()));
                 }
                 if (tempFound && !foundFlag)
                 {
                     // meg van az első WellKnownObjectMode, referencia mentése
                     targetMode = interfaceMode;
                     foundFlag  = true;
                 }
             }
         }
     }
     if (type.BaseType != null && !type.BaseType.Equals(typeof(ProxyBase)) && !type.BaseType.Equals(typeof(Object)))
     {
         CheckObjectMode(type.BaseType, ref targetMode, ref foundFlag);
     }
 }
Exemple #4
0
        /// <summary>
        /// Query and gets back the WellKnownObjectMode type of the provided contract
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="result">The result.</param>
        /// <returns>True, if the provided type found, otherwise False.</returns>
        public static bool GetWellKnownObjectMode(Type type, out WellKnownObjectModeEnum result)
        {
            if (type == null)
            {
                ThrowHelper.ThrowArgumentNullException("type");
            }

            bool found = false;

            result = WellKnownObjectModeEnum.PerSession;

            ServiceContractAttribute scAnnotation = TypeHelper.GetAttribute <ServiceContractAttribute>(type);

            if (scAnnotation != null)
            {
                result = scAnnotation.WellKnownObjectMode;
                found  = true;
            }

            if (scAnnotation == null && type.GetInterfaces().Length > 0)
            {
                foreach (Type interfaceClass in type.GetInterfaces())
                {
                    scAnnotation = TypeHelper.GetAttribute <ServiceContractAttribute>(interfaceClass);
                    if (scAnnotation != null)
                    {
                        result = scAnnotation.WellKnownObjectMode;
                        found  = true;
                    }
                    else
                    {
                        found = GetWellKnownObjectMode(interfaceClass, out result);
                    }
                    if (found)
                    {
                        break;
                    }
                }
            }
            if (!found && type.BaseType != null && !type.BaseType.Equals(typeof(ProxyBase)) && !type.BaseType.Equals(typeof(Object)))
            {
                found = GetWellKnownObjectMode(type.BaseType, out result);
            }

            return(found);
        }
Exemple #5
0
        /// <summary>
        /// Channels the receive message event handler.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="Forge.Net.Remoting.Channels.ReceiveMessageEventArgs"/> instance containing the event data.</param>
        protected override void ChannelReceiveMessageEventHandler(object sender, ReceiveMessageEventArgs e)
        {
            if (LOGGER.IsDebugEnabled)
            {
                LOGGER.Debug(string.Format("Executing service method. SessionId: '{0}', {1}", e.SessionId, e.Message.ToString()));
            }

            Channel  channel   = (Channel)sender;
            String   sessionId = e.SessionId;
            IMessage message   = e.Message;

            // Request és response message type jöhet
            // Request mode
            // Response mode
            // Datagram mode - nincs válasz
            if (message.MessageType == MessageTypeEnum.Acknowledge || message.MessageType == MessageTypeEnum.Response)
            {
                // HIBA: nem megfelelő üzenet típus (implementációs hiba?)
                String errorMsg = String.Format("Invalid message type received: {0}. This may be an implementation error in the client proxy.", message.MessageType);
                if (LOGGER.IsErrorEnabled)
                {
                    LOGGER.Error(errorMsg);
                }
            }
            else
            {
                RequestMessage rm = (RequestMessage)message;

                if (MessageInvokeModeEnum.RequestCallback.Equals(rm.MessageInvokeMode))
                {
                    return;
                }

                String contractName = rm.ContractName;
                Type   contractType = null;
                try
                {
                    contractType = TypeHelper.GetTypeFromString(contractName);
                }
                catch (Exception ex)
                {
                    // HIBA: ez a típus nem szerepel a ClassPath-ban
                    try
                    {
                        SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to resolve this type of contract '{0}'. Type has not found.", rm.ContractName), ex), channel.DefaultErrorResponseTimeout);
                    }
                    catch (Exception innerEx)
                    {
                        // válaszüzenet küldése sikertelen
                        if (LOGGER.IsErrorEnabled)
                        {
                            LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                        }
                    }
                    return;
                }
                ContractServiceSideDescriptor descriptor = null;
                lock (mContractDescriptors)
                {
                    if (mContractDescriptors.ContainsKey(contractType))
                    {
                        descriptor = mContractDescriptors[contractType];
                    }
                    else
                    {
                        // HIBA: ez a contract nincs nyilvántartva
                        try
                        {
                            SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("This type of contract '{0}' has not been registered.", contractType.FullName)), channel.DefaultErrorResponseTimeout);
                        }
                        catch (Exception innerEx)
                        {
                            // válaszüzenet küldése sikertelen
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                            }
                        }
                        return;
                    }
                }
                Type implType = null;
                lock (descriptor)
                {
                    if (descriptor.ImplementationPerChannel.ContainsKey(channel.ChannelId))
                    {
                        implType = descriptor.ImplementationPerChannel[channel.ChannelId];
                    }
                    else if (descriptor.DefaultImplementationType != null)
                    {
                        implType = descriptor.DefaultImplementationType;
                    }
                    else
                    {
                        // HIBA: a contract a megadott channel-hez nem definiált implementációs típust
                        try
                        {
                            SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to find implementation for this type of contract '{0}' and channel id: '{1}'.", contractType.FullName, channel.ChannelId)), channel.DefaultErrorResponseTimeout);
                        }
                        catch (Exception innerEx)
                        {
                            // válaszüzenet küldése sikertelen
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                            }
                        }
                        return;
                    }
                }
                Object instance = null;
                WellKnownObjectModeEnum objectMode = WellKnownObjectModeEnum.PerSession;
                ContractValidator.GetWellKnownObjectMode(contractType, out objectMode);
                if (objectMode == WellKnownObjectModeEnum.PerSession)
                {
                    // constructor keresése a Channel és String paraméterlistával, ha még ehhez a session-hez nem létezik instance
                    long proxyId = -1;
                    try
                    {
                        proxyId = (long)rm.Context[ProxyBase.PROXY_ID];
                    }
                    catch (Exception ex)
                    {
                        // HIBA: hiányzó vagy rossz formátumú ProxyId
                        try
                        {
                            SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException("Unable to parse PROXY_ID from call context.", ex), channel.DefaultErrorResponseTimeout);
                        }
                        catch (Exception innerEx)
                        {
                            // válaszüzenet küldése sikertelen
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                            }
                        }
                        return;
                    }
                    lock (mContractAndInstancePerSessionAndChannel)
                    {
                        foreach (ContractAndInstanceStruct s in mContractAndInstancePerSessionAndChannel)
                        {
                            if (s.Channel.Equals(channel) && s.ContractType.Equals(contractType) && s.SessionId.Equals(sessionId) && s.ImplType.Equals(implType) && s.ProxyId == proxyId)
                            {
                                instance = s.Instance;
                                break;
                            }
                        }
                        if (instance == null)
                        {
                            // még nem létezik a proxy példány, létre kell hozni
                            try
                            {
                                ConstructorInfo c = implType.GetConstructor(new Type[] { typeof(Channel), typeof(String) });
                                instance = c.Invoke(new object[] { channel, sessionId });
                                RegisterProxy(channel, contractType, implType, sessionId, proxyId, (ProxyBase)instance);
                            }
                            catch (Exception ex)
                            {
                                // HIBA: sikertelen az instance létrehozása
                                try
                                {
                                    SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to instantiate type '{0}'. Public constructor is not accessible/found with parameter types: '{1}' and '{2}'.", implType.FullName, typeof(Channel).FullName, typeof(String).FullName), ex), channel.DefaultErrorResponseTimeout);
                                }
                                catch (Exception innerEx)
                                {
                                    // válaszüzenet küldése sikertelen
                                    if (LOGGER.IsErrorEnabled)
                                    {
                                        LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                                    }
                                }
                                return;
                            }
                        }
                    }
                }
                else if (objectMode == WellKnownObjectModeEnum.Singleton)
                {
                    // üres constructor kell, ha még nem létezik az instance
                    lock (mSingletonContainer)
                    {
                        if (mSingletonContainer.ContainsKey(implType))
                        {
                            instance = mSingletonContainer[implType];
                        }
                        else
                        {
                            try
                            {
                                // még nem volt létrehozva
                                instance = implType.GetConstructor(new Type[] { }).Invoke(null);
                                mSingletonContainer.Add(implType, instance);
                            }
                            catch (Exception ex)
                            {
                                // HIBA: sikertelen az instance létrehozása
                                try
                                {
                                    SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to instantiate type '{0}'. Public empty constructor is not accessible/found.", implType.FullName), ex), channel.DefaultErrorResponseTimeout);
                                }
                                catch (Exception innerEx)
                                {
                                    // válaszüzenet küldése sikertelen
                                    if (LOGGER.IsErrorEnabled)
                                    {
                                        LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                                    }
                                }
                                return;
                            }
                        }
                    }
                }
                else
                {
                    // üres constructor kell, példányosítás mindig megtörténik
                    try
                    {
                        // még nem volt létrehozva
                        instance = implType.GetConstructor(new Type[] { }).Invoke(null);
                    }
                    catch (Exception ex)
                    {
                        // HIBA: sikertelen az instance létrehozása
                        try
                        {
                            SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to instantiate type '{0}'. Public empty constructor is not accessible/found.", implType.FullName), ex), channel.DefaultErrorResponseTimeout);
                        }
                        catch (Exception innerEx)
                        {
                            // válaszüzenet küldése sikertelen
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                            }
                        }
                        return;
                    }
                }

                // meg van az instance, lehet reflection-nel hívni a metódusára
                Type[]   methodParamTypes = null;
                Object[] paramValues      = null;
                if (rm.MethodParameters != null)
                {
                    methodParamTypes = new Type[rm.MethodParameters.Length];
                    paramValues      = new Object[rm.MethodParameters.Length];
                    for (int i = 0; i < rm.MethodParameters.Length; i++)
                    {
                        try
                        {
                            methodParamTypes[i] = TypeHelper.GetTypeFromString(rm.MethodParameters[i].ClassName);
                        }
                        catch (Exception ex)
                        {
                            // HIBA: a paraméter egy típusa nem szerepel a Domainben, így nem feloldható, ismeretlen
                            try
                            {
                                SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to resolve parameter type '{0}'. Type has not found.", rm.MethodParameters[i].ClassName), ex), channel.DefaultErrorResponseTimeout);
                            }
                            catch (Exception innerEx)
                            {
                                // válaszüzenet küldése sikertelen
                                if (LOGGER.IsErrorEnabled)
                                {
                                    LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                                }
                            }
                            return;
                        }
                        paramValues[i] = rm.MethodParameters[i].Value;
                    }
                }

                MethodInfo m = null;
                try
                {
                    m = FindMethod(implType, rm.MethodName, methodParamTypes);
                }
                catch (Exception ex)
                {
                    // HIBA: a metódus név és paraméterlista alapján nem található
                    try
                    {
                        SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to find method '{0}' with parameter list: '{1}'.", rm.MethodName, methodParamTypes), ex), channel.DefaultErrorResponseTimeout);
                    }
                    catch (Exception innerEx)
                    {
                        // válaszüzenet küldése sikertelen
                        if (LOGGER.IsErrorEnabled)
                        {
                            LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                        }
                    }
                    return;
                }
                long returnTimeout = OperationContractAttribute.DEFAULT_METHOD_TIMEOUT;
                if (rm.MessageType == MessageTypeEnum.Request)
                {
                    MethodParameter[] mps = null;
                    if (m.GetParameters().Length > 0)
                    {
                        mps = new MethodParameter[m.GetParameters().Length];
                        for (int i = 0; i < m.GetParameters().Length; i++)
                        {
                            ParameterInfo pi = m.GetParameters()[i];
                            mps[i] = new MethodParameter(i, string.Format("{0}, {1}", pi.ParameterType.FullName, new AssemblyName(pi.ParameterType.Assembly.FullName).Name), null);
                        }
                    }
                    returnTimeout = ServiceBase.GetTimeoutByMethod(contractType, m.Name, mps, MethodTimeoutEnum.ReturnTimeout);
                    lock (mCallContextForReply)
                    {
                        mCallContextForReply.Add(Thread.CurrentThread, new CallContextForReply(channel, sessionId, rm, m.ReturnType, returnTimeout));
                    }
                }

                // visszatérési értéket fogadni
                Exception methodException = null;
                Object    result          = null;
                try
                {
                    result = m.Invoke(instance, paramValues);
                }
                catch (Exception ex)
                {
                    if (LOGGER.IsDebugEnabled)
                    {
                        LOGGER.Debug(string.Format("Service method threw an exception. SessionId: '{0}', {1}", e.SessionId, e.Message.ToString()), ex);
                    }
                    methodException = ex;
                }

                // válaszüzenet küldése
                bool needToSendResponse = false;
                Type returnType         = typeof(void);
                if (rm.MessageType == MessageTypeEnum.Request)
                {
                    lock (mCallContextForReply)
                    {
                        if (mCallContextForReply.ContainsKey(Thread.CurrentThread))
                        {
                            needToSendResponse = true;
                            returnType         = mCallContextForReply[Thread.CurrentThread].ReturnType;
                        }
                    }
                }
                if (needToSendResponse)
                {
                    try
                    {
                        SendResponse(channel, sessionId, rm, returnType, result, methodException, returnTimeout);
                    }
                    catch (Exception ex)
                    {
                        // válaszüzenet küldése sikertelen
                        if (LOGGER.IsErrorEnabled)
                        {
                            LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, ex.Message));
                        }
                    }
                    finally
                    {
                        lock (mCallContextForReply)
                        {
                            mCallContextForReply.Remove(Thread.CurrentThread);
                        }
                    }
                }
                // saját tulajdonú instance, ami implementálja az IDisposable interface-t és SingleCall, akkor ráhívok a Dispose() metódusra
                if (objectMode == WellKnownObjectModeEnum.SingleCall && instance is IDisposable)
                {
                    ((IDisposable)instance).Dispose();
                }
            }
        }
Exemple #6
0
 private static void CheckSingletonOrSingleCallContract(Type contractInterface, WellKnownObjectModeEnum referenceMode)
 {
     foreach (MethodInfo m in contractInterface.GetMethods())
     {
         OperationContractAttribute ocAnnotation = TypeHelper.GetAttribute <OperationContractAttribute>(m);
         if (ocAnnotation != null && ocAnnotation.Direction == OperationDirectionEnum.ClientSide)
         {
             throw new InvalidContractDefinitionException(String.Format("Invalid {0} on contract '{1}'. Current setting '{2}' is supported only on {3} with {4}.{5}. Current mode is {6}.",
                                                                        typeof(OperationDirectionEnum).Name, contractInterface.Name, ocAnnotation.Direction.ToString(), typeof(ServiceContractAttribute).Name, typeof(WellKnownObjectModeEnum).Name, WellKnownObjectModeEnum.PerSession.ToString(), referenceMode.ToString()));
         }
     }
 }
Exemple #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ServiceContractAttribute"/> class.
 /// </summary>
 /// <param name="wellKnownObjectMode">The well known object mode.</param>
 public ServiceContractAttribute(WellKnownObjectModeEnum wellKnownObjectMode)
 {
     WellKnownObjectMode = wellKnownObjectMode;
 }
Exemple #8
0
        /// <summary>
        /// Channels the receive message event handler.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="Forge.Net.Remoting.Channels.ReceiveMessageEventArgs"/> instance containing the event data.</param>
        protected override void ChannelReceiveMessageEventHandler(object sender, ReceiveMessageEventArgs e)
        {
            Channel  channel   = (Channel)sender;
            IMessage message   = e.Message;
            String   sessionId = e.SessionId;

            if (message.MessageType == MessageTypeEnum.Acknowledge || message.MessageType == MessageTypeEnum.Response)
            {
                // HIBA: nem megfelelő üzenet típus (implementációs hiba?)
                String errorMsg = String.Format("Invalid message type received: {0}. This may be an implementation error in the client proxy.", message.MessageType.ToString());
                if (LOGGER.IsErrorEnabled)
                {
                    LOGGER.Error(errorMsg);
                }
            }
            else
            {
                RequestMessage rm = (RequestMessage)message;

                if (MessageInvokeModeEnum.RequestService.Equals(rm.MessageInvokeMode))
                {
                    return;
                }

                String contractName = rm.ContractName;
                Type   contractType = null;
                try
                {
                    contractType = TypeHelper.GetTypeFromString(contractName);
                }
                catch (Exception ex)
                {
                    // HIBA: ez a típus nem szerepel a ClassPath-ban
                    try
                    {
                        SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to resolve this type of contract '{0}'. Type has not found.", rm.ContractName), ex), channel.DefaultErrorResponseTimeout);
                    }
                    catch (Exception innerEx)
                    {
                        // válaszüzenet küldése sikertelen
                        if (LOGGER.IsErrorEnabled)
                        {
                            LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                        }
                    }
                    return;
                }
                {
                    WellKnownObjectModeEnum mode = WellKnownObjectModeEnum.PerSession;
                    if (ContractValidator.GetWellKnownObjectMode(contractType, out mode) && mode != WellKnownObjectModeEnum.PerSession)
                    {
                        // HIBA: nem PerSession a contract, amit meghívnak
                        try
                        {
                            SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Contract {0} must be configured to {1}.", typeof(WellKnownObjectModeEnum).Name, WellKnownObjectModeEnum.PerSession.ToString())), channel.DefaultErrorResponseTimeout);
                        }
                        catch (Exception innerEx)
                        {
                            // válaszüzenet küldése sikertelen
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                            }
                        }
                        return;
                    }
                }
                lock (mContractDescriptors)
                {
                    if (!mContractDescriptors.ContainsKey(contractType))
                    {
                        // HIBA: ez a contract nincs nyilvántartva
                        try
                        {
                            SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("This type of contract '{0}' has not been registered.", contractType.Name)), channel.DefaultErrorResponseTimeout);
                        }
                        catch (Exception innerEx)
                        {
                            // válaszüzenet küldése sikertelen
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                            }
                        }
                        return;
                    }
                }
                long proxyId = -1;
                try
                {
                    proxyId = (long)rm.Context[ProxyBase.PROXY_ID];
                }
                catch (Exception ex)
                {
                    // HIBA: hiányzó vagy rossz formátumú ProxyId
                    try
                    {
                        SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException("Unable to parse PROXY_ID from call context.", ex), channel.DefaultErrorResponseTimeout);
                    }
                    catch (Exception innerEx)
                    {
                        // válaszüzenet küldése sikertelen
                        if (LOGGER.IsErrorEnabled)
                        {
                            LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                        }
                    }
                    return;
                }
                ProxyBase proxy = null;
                lock (mContractAndInstancePerSessionAndChannel)
                {
                    foreach (ContractAndInstanceStruct s in mContractAndInstancePerSessionAndChannel)
                    {
                        if (s.Channel.Equals(channel) && s.ContractType.Equals(contractType) && s.SessionId.Equals(sessionId) && s.ProxyId == proxyId)
                        {
                            proxy = s.Instance;
                            break;
                        }
                    }
                    if (proxy == null)
                    {
                        // HIBA: nem létezik a hivatkozott proxy példány
                        try
                        {
                            SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to find proxy on client side with ID: {0}", proxyId)), channel.DefaultErrorResponseTimeout);
                        }
                        catch (Exception innerEx)
                        {
                            // válaszüzenet küldése sikertelen
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                            }
                        }
                        return;
                    }
                }
                // meg van az instance, lehet reflection-nel hívni a metódusára
                Type[]   methodParamTypes = null;
                Object[] paramValues      = null;
                if (rm.MethodParameters != null)
                {
                    methodParamTypes = new Type[rm.MethodParameters.Length];
                    paramValues      = new Object[rm.MethodParameters.Length];
                    for (int i = 0; i < rm.MethodParameters.Length; i++)
                    {
                        try
                        {
                            methodParamTypes[i] = TypeHelper.GetTypeFromString(rm.MethodParameters[i].ClassName);
                        }
                        catch (Exception ex)
                        {
                            // HIBA: a paraméter egy típusa nem szerepel a CLASSPATH-ban, így nem feloldható, ismeretlen
                            try
                            {
                                SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to resolve parameter type '{0}'. Type has not found.", rm.MethodParameters[i].ClassName), ex), channel.DefaultErrorResponseTimeout);
                            }
                            catch (Exception innerEx)
                            {
                                // válaszüzenet küldése sikertelen
                                if (LOGGER.IsErrorEnabled)
                                {
                                    LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                                }
                            }
                            return;
                        }
                        paramValues[i] = rm.MethodParameters[i].Value;
                    }
                }

                MethodInfo m = null;
                try
                {
                    m = FindMethod(proxy.GetType(), rm.MethodName, methodParamTypes);
                }
                catch (Exception ex)
                {
                    // HIBA: a metódus név és paraméterlista alapján nem található
                    try
                    {
                        SendResponse(channel, sessionId, rm, typeof(void), null, new MethodInvocationException(String.Format("Unable to find method '{0}' with parameter list: '{1}'.", rm.MethodName, methodParamTypes), ex), channel.DefaultErrorResponseTimeout);
                    }
                    catch (Exception innerEx)
                    {
                        // válaszüzenet küldése sikertelen
                        if (LOGGER.IsErrorEnabled)
                        {
                            LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, innerEx.Message));
                        }
                    }
                    return;
                }
                long returnTimeout = OperationContractAttribute.DEFAULT_METHOD_TIMEOUT;
                if (rm.MessageType == MessageTypeEnum.Request)
                {
                    MethodParameter[] mps = null;
                    if (m.GetParameters().Length > 0)
                    {
                        mps = new MethodParameter[m.GetParameters().Length];
                        for (int i = 0; i < m.GetParameters().Length; i++)
                        {
                            ParameterInfo pi = m.GetParameters()[i];
                            mps[i] = new MethodParameter(i, string.Format("{0}, {1}", pi.ParameterType.FullName, new AssemblyName(pi.ParameterType.Assembly.FullName).Name), null);
                        }
                    }
                    returnTimeout = ServiceBase.GetTimeoutByMethod(contractType, m.Name, mps, MethodTimeoutEnum.ReturnTimeout);
                    lock (mCallContextForReply)
                    {
                        mCallContextForReply.Add(Thread.CurrentThread, new CallContextForReply(channel, sessionId, rm, m.ReturnType, returnTimeout));
                    }
                }

                // visszatérési értéket fogadni
                Exception methodException = null;
                Object    result          = null;
                try
                {
                    result = m.Invoke(proxy, paramValues);
                }
                catch (Exception ex)
                {
                    methodException = ex;
                }

                // válaszüzenet küldése
                bool needToSendResponse = false;
                Type returnType         = typeof(void);
                if (rm.MessageType == MessageTypeEnum.Request)
                {
                    lock (mCallContextForReply)
                    {
                        if (mCallContextForReply.ContainsKey(Thread.CurrentThread))
                        {
                            needToSendResponse = true;
                            returnType         = mCallContextForReply[Thread.CurrentThread].ReturnType;
                        }
                    }
                }
                if (needToSendResponse)
                {
                    try
                    {
                        SendResponse(channel, sessionId, rm, returnType, result, methodException, returnTimeout);
                    }
                    catch (Exception ex)
                    {
                        // válaszüzenet küldése sikertelen
                        if (LOGGER.IsErrorEnabled)
                        {
                            LOGGER.Error(String.Format(AUTO_SEND_REPLY_ERROR_MSG, ex.Message));
                        }
                    }
                    finally
                    {
                        lock (mCallContextForReply)
                        {
                            mCallContextForReply.Remove(Thread.CurrentThread);
                        }
                    }
                }
            }
        }