Example #1
0
        private static void SendResponse(Task previous, ServerTransport transport, ServerResponseContext context, Tuple <RpcServer, long, int?, string> sessionState)
        {
            if (context == null)
            {
                if (previous.IsFaulted)
                {
                    try
                    {
                        previous.Exception.Handle(inner => inner is OperationCanceledException);
                    }
                    catch (AggregateException exception)
                    {
                        InvocationHelper.HandleInvocationException(
                            sessionState.Item2,
                            MessageType.Notification,
                            null,
                            sessionState.Item4,
                            exception,
                            sessionState.Item1.Configuration.IsDebugMode
                            );
                    }
                }

                previous.Dispose();
                return;
            }

            switch (previous.Status)
            {
            case TaskStatus.Canceled:
            {
                context.Serialize <object>(null, new RpcErrorMessage(RpcError.TimeoutError, "Server task exceeds execution timeout.", null), null);
                break;
            }

            case TaskStatus.Faulted:
            {
                context.Serialize <object>(null, new RpcErrorMessage(RpcError.RemoteRuntimeError, "Dispatcher throws exception.", previous.Exception.ToString()), null);
                break;
            }
            }

            previous.Dispose();
            transport.Send(context);
        }
Example #2
0
        /// <summary>
        ///		Sets the return value to the <see cref="ServerResponseContext"/>.
        /// </summary>
        /// <typeparam name="T">The type of the return value.</typeparam>
        /// <param name="context">The <see cref="ServerResponseContext"/> to be set the return value.</param>
        /// <param name="returnValue">The return value to be set.</param>
        /// <exception cref="ArgumentNullException">
        ///		<paramref name="context"/> is <c>null</c>.
        /// </exception>
        protected void SetReturnValue <T>(ServerResponseContext context, T returnValue)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            Contract.EndContractBlock();

            context.Serialize(returnValue, RpcErrorMessage.Success, this.SerializationContext.GetSerializer <T>());
        }
Example #3
0
        /// <summary>
        ///		Sets the exception to the <see cref="ServerResponseContext"/> as called method failure.
        /// </summary>
        /// <param name="context">The <see cref="ServerResponseContext"/> to be set the error.</param>
        /// <param name="operationId">The ID of operation which causes <paramref name="exception"/>.</param>
        /// <param name="exception">The exception to be set as the RPC error.</param>
        /// <exception cref="ArgumentNullException">
        ///		<paramref name="context"/> is <c>null</c>.
        ///		Or, <paramref name="exception"/> is <c>null</c>.
        /// </exception>
        /// <remarks>
        ///		You should use <see cref="RpcException"/> derived class to represent application error.
        ///		The runtime does not interpret other exception types except <see cref="ArgumentException"/> derviced class,
        ///		so they are represented as <see cref="RpcError.CallError"/> in the lump.
        ///		(<see cref="ArgumentException"/> derviced class is transformed to <see cref="P:RpcError.ArgumentError"/>.
        /// </remarks>
        protected void SetException(ServerResponseContext context, string operationId, Exception exception)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (exception == null)
            {
                throw new ArgumentNullException("exception");
            }

            Contract.EndContractBlock();

            context.Serialize <MessagePackObject>(MessagePackObject.Nil, InvocationHelper.HandleInvocationException(exception, operationId, this.IsDebugMode), this.SerializationContext.GetSerializer <MessagePackObject>());
        }
Example #4
0
        /// <summary>
        ///		Dispatches the specified request, and dispatches the response to the specified transport.
        /// </summary>
        /// <param name="serverTransport">The server transport the response to be dispatched.</param>
        /// <param name="requestContext">The request context.</param>
        internal void Dispatch(ServerTransport serverTransport, ServerRequestContext requestContext)
        {
            Contract.Requires(serverTransport != null);
            Contract.Requires(requestContext != null);

            ServerResponseContext responseContext = null;

            if (requestContext.MessageType == MessageType.Request)
            {
                responseContext = serverTransport.Manager.GetResponseContext(requestContext);
            }

            Task task;
            var  operation = this.Dispatch(requestContext.MethodName);

            if (operation == null)
            {
                var error = new RpcErrorMessage(RpcError.NoMethodError, "Operation does not exist.", null);
                InvocationHelper.TraceInvocationResult <object>(
                    requestContext.SessionId,
                    requestContext.MessageType,
                    requestContext.MessageId.GetValueOrDefault(),
                    requestContext.MethodName,
                    error,
                    null
                    );

                if (responseContext != null)
                {
                    task = Task.Factory.StartNew(() => responseContext.Serialize <object>(null, error, null));
                }
                else
                {
                    return;
                }
            }
            else
            {
                task = operation(requestContext, responseContext);
            }

            var sessionState = Tuple.Create(this._server, requestContext.SessionId, requestContext.MessageType == MessageType.Request ? requestContext.MessageId : default(int?), requestContext.MethodName);

#if NET_4_5
            task.ContinueWith((previous, state) =>
            {
                var tuple = state as Tuple < ServerTransport, ServerResponseContext, Tuple <RpcServer, long, int?, string>;
                SendResponse(previous, tuple.Item1, tuple.Item2, tuple.Item3)
            },
                              Tuple.Create(serverTransport, responseContext, sessionState)
                              ).ContinueWith((previous, state) =>
            {
                HandleSendFailure(previous, state as Tuple <RpcServer, long, int?, string>);
            },
                                             TaskContinuationOptions.OnlyOnFaulted,
                                             sessionState
                                             );
#else
            task.ContinueWith(previous =>
            {
                SendResponse(previous, serverTransport, responseContext, sessionState);
            }
                              ).ContinueWith(previous =>
            {
                HandleSendFailure(previous, sessionState);
            },
                                             TaskContinuationOptions.OnlyOnFaulted
                                             );
#endif
        }