/// <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 } ); }
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"); }; }
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"); }; }
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); } }
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); } }
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); } }
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);
/// <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 }