Пример #1
0
        internal static bool HandleTransportExceptionHelper(Exception exception)
        {
            //if (exception == null)
            // throw
            ExceptionHandler exceptionHandler = ExceptionHandler.TransportExceptionHandler;

            if (exceptionHandler == null)
            {
                return(false);
            }
            try
            {
                if (!exceptionHandler.HandleException(exception))
                {
                    return(false);
                }
            }
            catch (Exception ex)
            {
                //if (IsFatal(ex))
                {
                    //  throw;
                }
                //else
                {
                    //if (ShouldTraceError)
                    RpcTrace.Error(ex);
                    return(false);
                }
            }
            // if (ShouldTraceError)
            //     TraceHandledException(exception, TraceEventType.Error);
            return(true);
        }
Пример #2
0
        private Message invokeContract(IRpcCallInfo call, MessageRequest request, Type contractType)
        {
            OperationDispatchBase operation;
            bool operationExists = _operations.IdToOperation.TryGetValue(request.Operation, out operation);

            if (!operationExists)
            {
                var error        = new ActionNotSupportedException(string.Format("Server endpoint {0} with contract {1} does not supports operation with id = {2}. Check that client and server use the same version of contract and binding. ", _endpoint._address, contractType, request.Operation));
                var faultMessage = new Message();
                faultMessage = makeFault(error, faultMessage);
                return(faultMessage);
            }
            OperationContext operationContext = SetupOperationConext(call, request, contractType);
            Func <Message>   invokeAction     = () =>
            {
                OperationContext.Current = operationContext;
                if (_concurrency == ConcurrencyMode.Single)
                {
                    lock (this)
                    {
                        return(invokeContract(operation, request));
                    }
                }
                return(invokeContract(operation, request));
            };

            if (operation.Operation.IsOneWay)
            {
                Task task = Tasks.Factory.StartNew(invokeAction);
                task.ContinueWith(x => RpcTrace.Error(x.Exception), TaskContinuationOptions.OnlyOnFaulted);
                return(new Message());
            }
            else
            {
                return(invokeAction());
            }
        }
Пример #3
0
            public override IMessage Invoke(IMessage msg)
            {
                var input = (IMethodCallMessage)msg;


                //TODO: move to RpcCallbackProxy
                if (_router._context != null)
                {
                    _router._context.Initialize(_router._typeOfService, _router._address, _router._binding, _router._session, _router._syncContext);
                }

                Debug.Assert(input.MethodBase != null);
                Debug.Assert(input.MethodBase.DeclaringType != null);
                var iid = input.MethodBase.DeclaringType;

                if (iid == typeof(ICommunicationObject))
                {
                    //TODO: use something faster than string comparison
                    if (input.MethodName == "get_State")
                    {
                        return(new ReturnMessage(State, null, 0, input.LogicalCallContext, input));
                    }
                }
                else if (iid == typeof(IContextChannel))
                {
                    if (input.MethodName == "set_OperationTimeout")
                    {
                        OperationTimeout = (TimeSpan)input.InArgs[0];
                        return(new ReturnMessage(null, null, 0, input.LogicalCallContext, input));
                    }
                    if (input.MethodName == "get_OperationTimeout")
                    {
                        return(new ReturnMessage(OperationTimeout, null, 0, input.LogicalCallContext, input));
                    }
                }

                MethodResponse methodReturn;

                OperationDispatchBase op;

                if (_router._operations.TokenToOperation.TryGetValue(input.MethodBase.MetadataToken, out op))
                {
                    var r = new MessageRequest();
                    if (_router._session != null)
                    {
                        r.Session = _router._session;
                    }
                    r.Operation = op.Identifier;
                    var ps = new List <RpcParamData>();
                    for (int i = 0; i < op.Params.Count; i++)
                    {
                        var paramIdentifier = i;//TODO: try to make this connection with more inderect way
                        var stream          = new MemoryStream();
                        _router._serializer.WriteObject(stream, input.GetInArg(i));
                        ps.Add(new RpcParamData {
                            Identifier = paramIdentifier, Data = stream.ToArray()
                        });
                    }
                    r.Data.AddRange(ps.ToArray());
                    var rData = new MemoryStream();
                    _router._serializer.WriteObject(rData, r);
                    if (op is AsyncOperationDispatch)
                    {
                        object asyncState    = input.GetInArg(op.Params.Count + 1);
                        var    asyncCallback = (AsyncCallback)input.GetInArg(op.Params.Count);
                        Task   task          = Tasks.Factory.StartNew((x) =>
                        {
                            try
                            {
                                _router._operationPending.Reset();

                                byte[] result = null;


                                result = ExecuteRequest(rData);

                                var reply =
                                    (Message)
                                    _encoder.ReadObject(new MemoryStream(result),
                                                        typeof(Message));

                                applyReplyProcessing(reply);
                            }
                            catch (ExternalException ex)
                            {
                                throw HandleCommunicationError(ex);
                            }
                            catch (Exception ex)
                            {
                                throw;
                            }
                            finally
                            {
                                _router._operationPending.Set();
                            }
                            return(new ReturnMessage(null, null, 0, null, input));
                        }, asyncState);

                        task.ContinueWith(x =>
                        {
                            //TODO: do exception handling like in WCF
                            RpcTrace.Error(x.Exception);

                            if (asyncCallback != null)
                            {
                                asyncCallback(x);
                            }
                        }, TaskContinuationOptions.OnlyOnFaulted);

                        task.ContinueWith(x =>
                        {
                            if (asyncCallback != null)
                            {
                                asyncCallback(x);
                            }
                        }, TaskContinuationOptions.OnlyOnRanToCompletion);
                        return(new ReturnMessage(task, null, 0, null, input));
                    }
                    else if (op.Operation.IsOneWay)
                    {
                        Debug.Assert(op.MethodInfo.ReturnType == typeof(void));
                        try
                        {
                            _router._operationPending.Reset();

                            byte[] result = null;


                            result = ExecuteRequest(rData);

                            var reply = (Message)_encoder.ReadObject(new MemoryStream(result), typeof(Message));

                            try
                            {
                                applyReplyProcessing(reply);
                            }
                            catch (Exception ex)
                            {
                                return(new ReturnMessage(ex, input));
                            }
                        }
                        catch (ExternalException ex)
                        {
                            throw HandleCommunicationError(ex);
                        }
                        catch (Exception ex)
                        {
                            throw;
                        }
                        finally
                        {
                            _router._operationPending.Set();
                        }
                        return(new ReturnMessage(null, null, 0, null, input));
                    }

                    try
                    {
                        _router._operationPending.Reset();

                        byte[] result = null;

                        //BUG: using tasks adds  30% to simple local calls with bytes, and 10% longer then WCF...
                        //TODO: use native MS-RPC timeouts
                        //Task operation = Task.Factory.StartNew(() =>
                        //    {
                        result = ExecuteRequest(rData);
                        //    });
                        //var ended = operation.Wait(_operationTimeout);
                        //if (!ended)
                        //{
                        //    var timeourError =
                        //        new TimeoutException(
                        //            string.Format("The request channel timed out attempting to send after {0}",
                        //                          _operationTimeout));
                        //    return new ReturnMessage(timeourError,input);
                        //}

                        var reply = (Message)_encoder.ReadObject(new MemoryStream(result), typeof(Message));
                        applyReplyProcessing(reply);
                        if (op.MethodInfo.ReturnType != typeof(void))
                        {
                            var retVal = _router._serializer.ReadObject(new MemoryStream(reply.Data), op.MethodInfo.ReturnType);
                            var ret    = new ReturnMessage(retVal, null, 0, null, input);
                            return(ret);
                        }
                    }
                    catch (ExternalException ex)
                    {
                        var wrappedException = HandleCommunicationError(ex);
                        return(new ReturnMessage(wrappedException, input));
                    }
                    catch (Exception ex)
                    {
                        return(new ReturnMessage(ex, input));
                    }
                    finally
                    {
                        _router._operationPending.Set();
                    }
                    return(new ReturnMessage(null, null, 0, null, input));
                }
                //var error = new ActionNotSupportedException();
                //RpcTrace.Error();
                throw new InvalidOperationException(string.Format("Cannot find operation {0} on service {1}", input.MethodName, _service));
            }