示例#1
0
 /// <summary>
 ///		Raises the <see cref="E:ClientError"/> event.
 /// </summary>
 /// <param name="context">The context information.</param>
 /// <param name="rpcError">The RPC error.</param>
 internal void RaiseClientError(ServerRequestContext context, RpcErrorMessage rpcError)
 {
     this.OnClientError(
         new RpcClientErrorEventArgs(rpcError)
     {
         RemoteEndPoint = context.RemoteEndPoint,
         SessionId      = context.SessionId,
         MessageId      = context.MessageId
     }
         );
 }
示例#2
0
        public void TestInvokeAsync_Success_TaskSetSerializedReturnValue()
        {
            using (var server = new RpcServer())
                using (var transportManager = new NullServerTransportManager(server))
                    using (var transport = new NullServerTransport(transportManager))
                    {
                        ServerRequestContext  requestContext  = DispatchTestHelper.CreateRequestContext();
                        ServerResponseContext responseContext = DispatchTestHelper.CreateResponseContext(transport);
                        using (var result = new Target(null, RpcErrorMessage.Success).InvokeAsync(requestContext, responseContext))
                        {
                            result.Wait();
                        }

                        Assert.That(responseContext.GetReturnValueData(), Is.EqualTo(new byte[] { 123 }));
                        Assert.That(responseContext.GetErrorData(), Is.EqualTo(new byte[] { 0xC0 }));
                    }
        }
        public PlatronModule()
        {
            Get[ResultUrlRoute] = _ =>
            {
                var context = new ServerRequestContext(Request.Url);

                requests.OnNext(context);
                context.WaitForResponse(TimeSpan.FromMinutes(5));
                return AsXml(context.Response);
            };

            Post[ResultUrlRoute] = _ =>
            {
                // we could expect if incoming request was in POST, that their callback request will be POST too. But it is not.
                // Platron always sends response thru get.
                throw new InvalidOperationException("Not expected: callback as POST");
            };
        }
示例#4
0
        public PlatronModule()
        {
            Get[ResultUrlRoute] = _ =>
            {
                var context = new ServerRequestContext(Request.Url);

                requests.OnNext(context);
                context.WaitForResponse(TimeSpan.FromMinutes(5));
                return(AsXml(context.Response));
            };

            Post[ResultUrlRoute] = _ =>
            {
                // we could expect if incoming request was in POST, that their callback request will be POST too. But it is not.
                // Platron always sends response thru get.
                throw new InvalidOperationException("Not expected: callback as POST");
            };
        }
示例#5
0
        public void TestInvokeAsync_MethodError_TaskSetSerializedError()
        {
            using (var server = new RpcServer())
                using (var transportManager = new NullServerTransportManager(server))
                    using (var transport = new NullServerTransport(transportManager))
                    {
                        ServerRequestContext  requestContext  = DispatchTestHelper.CreateRequestContext();
                        ServerResponseContext responseContext = DispatchTestHelper.CreateResponseContext(transport);
                        using (var result = new Target(null, new RpcErrorMessage(RpcError.ArgumentError, MessagePackObject.Nil)).InvokeAsync(requestContext, responseContext))
                        {
                            result.Wait();
                        }

                        var error       = Unpacking.UnpackObject(responseContext.GetErrorData());
                        var errorDetail = Unpacking.UnpackObject(responseContext.GetReturnValueData());
                        Assert.That(error.Value.Equals(RpcError.ArgumentError.Identifier));
                        Assert.That(errorDetail.Value.IsNil, Is.True);
                    }
        }
示例#6
0
        public void TestInvokeAsync_FatalError_TaskSetSerializedError()
        {
            using (var server = new RpcServer())
                using (var transportManager = new NullServerTransportManager(server))
                    using (var transport = new NullServerTransport(transportManager))
                    {
                        ServerRequestContext  requestContext  = DispatchTestHelper.CreateRequestContext();
                        ServerResponseContext responseContext = DispatchTestHelper.CreateResponseContext(transport);
                        using (var result = new Target(new Exception("FAIL"), RpcErrorMessage.Success).InvokeAsync(requestContext, responseContext))
                        {
                            result.Wait();
                        }

                        var error       = Unpacking.UnpackObject(responseContext.GetErrorData());
                        var errorDetail = Unpacking.UnpackObject(responseContext.GetReturnValueData());
                        Assert.That(error.Value.Equals(RpcError.CallError.Identifier));
                        Assert.That(errorDetail.Value.IsNil, Is.False);
                    }
        }
示例#7
0
        public static ServerRequestContext WaitForRequest(TimeSpan timeout)
        {
            ServerRequestContext context = null;
            var timeToStop = new ManualResetEvent(false);

            using (Requests.Subscribe(
                       x =>
            {
                context = x;
                timeToStop.Set();
            },
                       () => timeToStop.Set()))
            {
                var requestReceived = timeToStop.WaitOne(timeout);
                if (!requestReceived)
                {
                    throw new InvalidOperationException("Request from platron didn't received");
                }

                return(context);
            }
        }
示例#8
0
        public sealed override Task InvokeAsync(ServerRequestContext requestContext, ServerResponseContext responseContext)
        {
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }

            Contract.Ensures(Contract.Result <Task>() != null);

            var messageId = requestContext.MessageId;
            var arguments = requestContext.ArgumentsUnpacker;

            bool readMustSuccess = arguments.Read();

            Contract.Assert(readMustSuccess, "Arguments is not an array.");
            Contract.Assert(arguments.IsArrayHeader);

            SafeStartLogicalOperation();
            if (MsgPackRpcServerDispatchTrace.ShouldTrace(MsgPackRpcServerDispatchTrace.OperationStart))
            {
                MsgPackRpcServerDispatchTrace.TraceData(
                    MsgPackRpcServerDispatchTrace.OperationStart,
                    "Operation starting.",
                    responseContext == null ? MessageType.Notification : MessageType.Request,
                    messageId,
                    this.OperationId
                    );
            }

            AsyncInvocationResult result;

            try
            {
                result = this.InvokeCore(arguments);
            }
            catch (Exception ex)
            {
                result = new AsyncInvocationResult(InvocationHelper.HandleInvocationException(requestContext.SessionId, requestContext.MessageType, requestContext.MessageId, this.OperationId, ex, this.IsDebugMode));
            }

            var tuple = Tuple.Create(this, requestContext.SessionId, messageId.GetValueOrDefault(), this.OperationId, responseContext, result.InvocationError);

            if (result.AsyncTask == null)
            {
                return(Task.Factory.StartNew(state => HandleInvocationResult(null, state as Tuple <AsyncServiceInvoker <T>, long, int, string, ServerResponseContext, RpcErrorMessage>), tuple));
            }
            else
            {
#if NET_4_5
                return
                    (result.AsyncTask.ContinueWith(
                         (previous, state) => HandleInvocationResult(
                             previous,
                             state as Tuple <AsyncServiceInvoker <T>, long, int, string, ServerResponseContext, RpcErrorMessage>
                             ),
                         tuple
                         ));
#else
                return
                    (result.AsyncTask.ContinueWith(
                         previous => HandleInvocationResult(
                             previous,
                             tuple
                             )
                         ));
#endif
            }
        }
 /// <summary>
 ///		Invokes target service operation asynchronously.
 /// </summary>
 /// <param name="requestContext">
 ///		The context object to hold request data.
 ///		Note that properties of the context is only valid until this method returns.
 ///		That is, it will be unpredectable state in the asynchronous operation.
 ///	</param>
 /// <param name="responseContext">
 ///		The context object to pack response value or error.
 ///		This is <c>null</c> for the notification messages.
 ///	</param>
 /// <returns>
 ///   <see cref="Task"/> to control entire process including sending response.
 /// </returns>
 public abstract Task InvokeAsync(ServerRequestContext requestContext, ServerResponseContext responseContext);
示例#10
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
        }