Beispiel #1
0
        /// <summary>
        /// Handles MessageReceived event of messenger.
        ///             It gets messages from server and invokes appropriate method.
        ///
        /// </summary>
        /// <param name="sender">Source of event</param><param name="e">Event arguments</param>
        private void RequestReplyMessenger_MessageReceived(object sender, MessageEventArgs e)
        {
            ScsRemoteInvokeMessage remoteInvokeMessage = e.Message as ScsRemoteInvokeMessage;

            if (remoteInvokeMessage == null)
            {
                return;
            }
            if (this._clientObject == null)
            {
                this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException("Client does not wait for method invocations by server."));
            }
            else
            {
                object returnValue;
                try
                {
                    returnValue = this._clientObject.GetType().GetMethod(remoteInvokeMessage.MethodName).Invoke(this._clientObject, remoteInvokeMessage.Parameters);
                }
                catch (TargetInvocationException ex)
                {
                    Exception innerException = ex.InnerException;
                    this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(innerException.Message, innerException));
                    return;
                }
                catch (Exception ex)
                {
                    this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(ex.Message, ex));
                    return;
                }
                this.SendInvokeResponse((IScsMessage)remoteInvokeMessage, returnValue, (ScsRemoteException)null);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Overrides message calls and translates them to messages to remote application.
        /// </summary>
        /// <param name="msg">Method invoke message (from RealProxy base class)</param>
        /// <returns>Method invoke return message (to RealProxy base class)</returns>
        public override IMessage Invoke(IMessage msg)
        {
            IMethodCallMessage message = msg as IMethodCallMessage;

            if (message == null)
            {
                return(null);
            }

            ScsRemoteInvokeMessage requestMessage = new ScsRemoteInvokeMessage
            {
                ServiceClassName = typeof(TProxy).Name,
                MethodName       = message.MethodName,
                Parameters       = message.InArgs
            };

            ScsRemoteInvokeReturnMessage responseMessage = _clientMessenger.SendMessageAndWaitForResponse(requestMessage, 10) as ScsRemoteInvokeReturnMessage;

            if (responseMessage == null)
            {
                return(null);
            }

            return(responseMessage.RemoteException != null
                       ? new ReturnMessage(responseMessage.RemoteException, message)
                       : new ReturnMessage(responseMessage.ReturnValue, null, 0, message.LogicalCallContext, message));
        }
Beispiel #3
0
        /// <summary>
        /// 将方法调用转换为远程方法调用
        /// </summary>
        /// <param name="method">代理方法</param>
        /// <param name="parameters">代理参数</param>
        /// <returns>方法返回结果</returns>
        public virtual object Intercept(MethodInfo method, object[] parameters)
        {
            if (method == null)
            {
                return(null);
            }

            var requestMessage = new ScsRemoteInvokeMessage
            {
                ServiceClassName = typeof(TProxy).Name,
                MethodName       = method.Name,
                Parameters       = parameters
            };

            var responseMessage = _clientMessenger.SendMessageAndWaitForResponse(requestMessage) as ScsRemoteInvokeReturnMessage;

            if (responseMessage == null)
            {
                return(null);
            }

            return(responseMessage.RemoteException == null
                ? responseMessage.ReturnValue
                : throw responseMessage.RemoteException);
        }
        /// <summary>
        /// Handles MessageReceived events of all clients, evaluates each message,
        ///             finds appropriate service object and invokes appropriate method.
        ///
        /// </summary>
        /// <param name="sender">Source of event</param><param name="e">Event arguments</param>
        private void Client_MessageReceived(object sender, MessageEventArgs e)
        {
            RequestReplyMessenger <IScsServerClient> requestReplyMessenger = (RequestReplyMessenger <IScsServerClient>)sender;
            ScsRemoteInvokeMessage remoteInvokeMessage = e.Message as ScsRemoteInvokeMessage;

            if (remoteInvokeMessage == null)
            {
                return;
            }
            try
            {
                IScsServiceClient scsServiceClient = this._serviceClients[requestReplyMessenger.Messenger.ClientId];
                if (scsServiceClient == null)
                {
                    requestReplyMessenger.Messenger.Disconnect();
                }
                else
                {
                    ScsServiceApplication.ServiceObject serviceObject = this._serviceObjects[remoteInvokeMessage.ServiceClassName];
                    if (serviceObject == null)
                    {
                        ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException("There is no service with name '" + remoteInvokeMessage.ServiceClassName + "'"));
                    }
                    else
                    {
                        try
                        {
                            serviceObject.Service.CurrentClient = scsServiceClient;
                            object returnValue;
                            try
                            {
                                returnValue = serviceObject.InvokeMethod(remoteInvokeMessage.MethodName, remoteInvokeMessage.Parameters);
                            }
                            finally
                            {
                                serviceObject.Service.CurrentClient = (IScsServiceClient)null;
                            }
                            ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, returnValue, (ScsRemoteException)null);
                        }
                        catch (TargetInvocationException ex)
                        {
                            Exception innerException = ex.InnerException;
                            ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(innerException.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, innerException));
                        }
                        catch (Exception ex)
                        {
                            ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException(ex.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, ex));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ScsServiceApplication.SendInvokeResponse((IMessenger)requestReplyMessenger, (IScsMessage)remoteInvokeMessage, (object)null, new ScsRemoteException("An error occured during remote service method call.", ex));
            }
        }
Beispiel #5
0
        /// <summary>
        /// Overrides message calls and translates them to messages to remote application.
        /// </summary>
        /// <param name="msg">Method invoke message (from RealProxy base class)</param>
        /// <returns>Method invoke return message (to RealProxy base class)</returns>
        public override IMessage Invoke(IMessage msg)
        {
            var message = msg as IMethodCallMessage;

            if (message == null)
            {
                return(null);
            }

            var requestMessage = new ScsRemoteInvokeMessage
            {
                ServiceClassName = typeof(TProxy).Name,
                MethodName       = message.MethodName,
                //Parameters = message.InArgs
                Parameters = message.Args
            };

            var responseMessage = _clientMessenger.SendMessageAndWaitForResponse(requestMessage) as ScsRemoteInvokeReturnMessage;

            if (responseMessage == null)
            {
                return(null);
            }

            /*
             * http://stackoverflow.com/questions/3081341/ref-argument-through-a-realproxy
             * The second parameter of ReturnMessage needs to contain the values of the ref and out parameters to pass back. You can get them by saving a reference to the array you pass in:
             *
             * public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
             * {
             * IMethodCallMessage call = msg as IMethodCallMessage;
             * var args = call.Args;
             * object returnValue = typeof(HelloClass).InvokeMember(call.MethodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, _hello, args);
             * return new ReturnMessage(returnValue, args, args.Length, call.LogicalCallContext, call);
             * }
             */
            object[] args  = null;
            int      largo = 0;

            if (responseMessage.Parameters != null)
            {
                args  = responseMessage.Parameters;
                largo = args.Length;
            }
            return(responseMessage.RemoteException != null
                       ? new ReturnMessage(responseMessage.RemoteException, message)
                       : new ReturnMessage(responseMessage.ReturnValue, args, largo, message.LogicalCallContext, message));
        }
Beispiel #6
0
        /// <summary>
        /// Handles MessageReceived event of messenger. It gets messages from server and invokes
        /// appropriate method.
        /// </summary>
        /// <param name="sender">Source of event</param>
        /// <param name="e">Event arguments</param>
        private void RequestReplyMessenger_MessageReceived(object sender, MessageEventArgs e)
        {
            // Cast message to ScsRemoteInvokeMessage and check it
            ScsRemoteInvokeMessage invokeMessage = e.Message as ScsRemoteInvokeMessage;

            if (invokeMessage == null)
            {
                return;
            }

            // Check client object.
            if (_clientObject == null)
            {
                SendInvokeResponse(invokeMessage, null, new ScsRemoteException("Client does not wait for method invocations by server."));
                return;
            }

            // Invoke method
            object returnValue;

            try
            {
                Type       type   = _clientObject.GetType();
                MethodInfo method = type.GetMethod(invokeMessage.MethodName);
                returnValue = method.Invoke(_clientObject, invokeMessage.Parameters);
            }
            catch (TargetInvocationException ex)
            {
                Exception innerEx = ex.InnerException;
                if (innerEx != null)
                {
                    SendInvokeResponse(invokeMessage, null, new ScsRemoteException(innerEx.Message, innerEx));
                }
                return;
            }
            catch (Exception ex)
            {
                SendInvokeResponse(invokeMessage, null, new ScsRemoteException(ex.Message, ex));
                return;
            }

            // Send return value
            SendInvokeResponse(invokeMessage, returnValue, null);
        }
        /// <summary>
        /// Handles MessageReceived events of all clients, evaluates each message, finds appropriate
        /// service object and invokes appropriate method.
        /// </summary>
        /// <param name="sender">Source of event</param>
        /// <param name="e">Event arguments</param>
        private void Client_MessageReceived(object sender, MessageEventArgs e)
        {
            // Get RequestReplyMessenger object (sender of event) to get client
            RequestReplyMessenger <IScsServerClient> requestReplyMessenger = (RequestReplyMessenger <IScsServerClient>)sender;

            // Cast message to ScsRemoteInvokeMessage and check it
            ScsRemoteInvokeMessage invokeMessage = e.Message as ScsRemoteInvokeMessage;

            if (invokeMessage == null)
            {
                return;
            }

            try
            {
                // Get client object
                IScsServiceClient client = _serviceClients[requestReplyMessenger.Messenger.ClientId];
                if (client == null)
                {
                    requestReplyMessenger.Messenger.Disconnect();
                    return;
                }

                // Get service object
                ServiceObject serviceObject = _serviceObjects[invokeMessage.ServiceClassName];
                if (serviceObject == null)
                {
                    SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException("There is no service with name '" + invokeMessage.ServiceClassName + "'"));
                    return;
                }

                // Invoke method
                try
                {
                    // Set client to service, so user service can get client in service method using
                    // CurrentClient property.
                    object returnValue;
                    serviceObject.Service.CurrentClient = client;
                    try
                    {
                        returnValue = serviceObject.InvokeMethod(invokeMessage.MethodName, invokeMessage.Parameters);
                    }
                    finally
                    {
                        // Set CurrentClient as null since method call completed
                        serviceObject.Service.CurrentClient = null;
                    }

                    // Send method invocation return value to the client
                    SendInvokeResponse(requestReplyMessenger, invokeMessage, returnValue, null);
                }
                catch (TargetInvocationException ex)
                {
                    Exception innerEx = ex.InnerException;
                    if (innerEx != null)
                    {
                        SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException(innerEx.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, innerEx));
                    }
                }
                catch (Exception ex)
                {
                    SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException(ex.Message + Environment.NewLine + "Service Version: " + serviceObject.ServiceAttribute.Version, ex));
                }
            }
            catch (Exception ex)
            {
                SendInvokeResponse(requestReplyMessenger, invokeMessage, null, new ScsRemoteException("An error occured during remote service method call.", ex));
            }
        }