/// <summary> /// Sends asynchronous request to the server. /// </summary> /// <param name="requestId">Request ID.</param> /// <param name="callParameters">Call parameters.</param> /// <returns> /// Returns <c>null</c> on success or result containing error status /// on failure. /// </returns> private IRpcResult SendAsyncRequest(uint requestId, RpcCallParameters callParameters) { if (!callParameters.IsAsync) { throw new InvalidOperationException("Call is not asychronous."); } IRpcResult result = null; try { var stream = this.GetChannelStream(); var call = this.ProtocolObjectFactory.BuildCall(callParameters); this.ProtocolObjectFactory.WriteMessage(stream, requestId, call, null); this.log.TraceFormat("Asynchronous message sent {0}.", requestId); } catch (IOException ex) { this.log.DebugFormat("Exception while sending a message {0}. Disconnected?", ex, requestId); this.CloseChannel(); result = this.ProtocolObjectFactory.CreateRpcResult(); result.Status = RpcStatus.ChannelFailure; } return(result); }
public void WriteMessage(Stream stream, uint requestId, IRpcCall call, IRpcResult result) { // TODO: It may be more efficient to write complete request to a memory buffer first // and then write into the stream to avoid blocking other threads while // data actually being serialized. using (var writer = new BinaryWriter(stream, Encoding.UTF8, true)) { lock (this.writeLock) { writer.Write(requestId); byte contentFlags = 0; contentFlags |= call != null ? ProtocolObjectFactory.HasCallFlag : (byte)0; contentFlags |= result != null ? ProtocolObjectFactory.HasResultFlag : (byte)0; writer.Write(contentFlags); if (call != null) { ((RpcCall)call).Serialize(writer); } if (result != null) { ((RpcResult)result).Serialize(writer); } } } }
private void ExecuteRequest(ServerContext context, IRpcCall call, IRpcResult result) { IRpcServiceStub service; // Check whether the called method is for service or transient object. // The service are identified by name and the lifetime is controlled by the // server side. // The transient objects are registered as result of a method call and // identified by object ID. The lifetime of transient object is // controlled by the client. if (call.ObjectId != 0) { // Try to find object that corresponds to the marshalled interface. service = context.ObjectManager.GetInstance(call.ObjectId); if (service == null) { result.Status = RpcStatus.UnknownInterface; this.log.ErrorFormat( "Cannot find object '{0}' with '{1}.{2}' interface", call.ObjectId, call.ServiceName, call.MethodName); } } else { // Try to find service in global scope and then within connection context. service = this.objectManager.GetService(call.ServiceName); if (service == null) { service = context.ObjectManager.GetService(call.ServiceName); if (service == null) { this.log.ErrorFormat( "Cannot find service with interface '{0}.{1}'", call.ServiceName, call.MethodName); result.Status = RpcStatus.UnknownInterface; } } } if (service != null) { this.log.TraceFormat("Calling method '{0}.{1}'.", call.ServiceName, call.MethodName); service.CallMethod(context, call, result); } else { Debug.Assert(result.Status != RpcStatus.Succeeded, "Result cannot be a success"); } }
/// <summary> /// Sends specified request to the server. /// </summary> /// <param name="requestId">Request ID.</param> /// <param name="callParameters">Call parameters.</param> /// <returns> /// Returns <c>null</c> on success or result containing error status /// on failure. /// </returns> private IRpcResult SendSyncRequest(uint requestId, RpcCallParameters callParameters) { if (callParameters.IsAsync) { throw new InvalidOperationException("Call must be synchronous."); } lock (this.pendingCallsLock) { this.pendingCalls.Add(requestId, new PendingCall()); this.log.TraceFormat("Registered request {0} to wait for reply.", requestId); } IRpcResult result = null; try { var stream = this.GetChannelStream(); var call = this.ProtocolObjectFactory.BuildCall(callParameters); this.ProtocolObjectFactory.WriteMessage(stream, requestId, call, null); this.log.TraceFormat("Message sent {0}.", requestId); } catch (IOException ex) { this.log.Debug("Exception while sending a message. Disconnected?", ex); this.CloseChannel(); lock (this.pendingCallsLock) { if (!this.pendingCalls.ContainsKey(requestId)) { // This should really never happen, unless there is a logic error. result = this.ProtocolObjectFactory.CreateRpcResult(); result.Status = RpcStatus.InternalError; this.log.ErrorFormat("Failed to find pending call {0}.", requestId); Debug.Fail("Failed to find pending call."); } else { this.pendingCalls.Remove(requestId); } } result = this.ProtocolObjectFactory.CreateRpcResult(); result.Status = RpcStatus.ChannelFailure; } return(result); }
public void CallMethod(IServerContext context, IRpcCall rpcCall, IRpcResult result) { if (rpcCall.MethodName == "Ping") { if (rpcCall.CallData == null || rpcCall.CallData.Length != 4) { result.Status = RpcStatus.InvalidCallParameter; return; } var counter = BitConverter.ToInt32(rpcCall.CallData, 0); ++counter; result.ResultData = BitConverter.GetBytes(counter); } else { result.Status = RpcStatus.UnknownMethod; } }
public void CallMethod(IServerContext context, IRpcCall rpcCall, IRpcResult rpcResult) { rpcResult.Status = RpcStatus.Succeeded; if (rpcCall.MethodName == "Method_V_V") { this.Impl.Method_V_V(context); } else if (rpcCall.MethodName == "Method_V_M") { var input = new StructType(); input.MergeFrom(new CodedInputStream(rpcCall.CallData)); this.Impl.Method_V_M(context, input); rpcResult.ResultData = new Empty().ToByteArray(); } else if (rpcCall.MethodName == "Method_M_V") { var result = this.Impl.Method_M_V(context); rpcResult.ResultData = result.ToByteArray(); } else if (rpcCall.MethodName == "Method_M_M") { var input = new StructType(); input.MergeFrom(new CodedInputStream(rpcCall.CallData)); var result = this.Impl.Method_M_M(context, input); rpcResult.ResultData = result.ToByteArray(); } else if (rpcCall.MethodName == "AsyncMethod_V_V") { this.Impl.AsyncMethod_V_V(context); } else if (rpcCall.MethodName == "AsyncMethod_V_M") { var input = new StructType(); input.MergeFrom(new CodedInputStream(rpcCall.CallData)); this.Impl.AsyncMethod_V_M(context, input); } else { rpcResult.Status = RpcStatus.UnknownMethod; } }
public void CallMethod(IServerContext context, IRpcCall rpcCall, IRpcResult rpcResult) { }