/// <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); }
/// <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); }
internal void SendEvent(RpcCallParameters callParameters, IChannel channel) { var cachedCall = this.ProtocolObjectFactory.BuildCall(callParameters); if (channel != null) { this.ProtocolObjectFactory.WriteMessage(channel.Stream, 0, cachedCall, null); } else { lock (this.activeConnectionsLock) { foreach (var c in this.activeConnections) { this.ProtocolObjectFactory.WriteMessage(c.Channel.Stream, 0, cachedCall, null); } } } }
/// <summary> /// Sends request to the server. /// </summary> /// <param name="rpcCallParameters">Call parameters.</param> /// <returns> /// <para> /// Returns <see cref="RpcStatus.Succeeded"/> on success or error status /// on failure. /// </para> /// <para> /// Asynchronous call success indicates that request was sent successfully /// and <see cref="IRpcResult.ResultData"/> is unfilled. /// </para> /// <para> /// Synchronous call success indicates that the request was sent and reply /// received successfully and <see cref="IRpcResult.ResultData"/> contains /// received response. /// </para> /// </returns> public IRpcResult CallService(RpcCallParameters rpcCallParameters) { this.log.DebugFormat( "Calling service {0}.{1} (async:{2})", rpcCallParameters.ServiceName, rpcCallParameters.MethodName, rpcCallParameters.IsAsync); this.EnsureConnection(); uint requestId; lock (this.requestIdLock) { requestId = ++this.lastRequestId; } this.log.TraceFormat("Request ID {0}", requestId); IRpcResult result; if (rpcCallParameters.IsAsync) { result = this.SendAsyncRequest(requestId, rpcCallParameters); } else { result = this.SendSyncRequest(requestId, rpcCallParameters); if (result == null) { return(this.AwaitResult(requestId)); } } if (result == null) { result = this.ProtocolObjectFactory.CreateRpcResult(); result.Status = RpcStatus.Succeeded; } return(result); }