private async void Process() { while (!Queue.IsEmpty) { LogDebug("Attempting to process queued messages..."); bool success = false; if (!IsClosed) { CFXEnvelope[] messages = Queue.PeekMany(AmqpCFXEndpoint.MaxMessagesPerTransmit.Value); if (messages != null && messages.Any()) { try { Message msg = AmqpUtilities.MessageFromEnvelopes(messages, AmqpCFXEndpoint.Codec.Value); SenderLink.Send(msg); success = true; } catch (Exception ex) { LogError(ex); AppLog.Error(ex); } if (success) { Queue.Dequeue(messages.Length); } int remainingCount = Queue.Count; if (success) { LogDebug($"{messages.Length} messages transmitted. {Queue.Count} messages remaining in spool."); } else { LogDebug($"Messages NOT transmitted. {Queue.Count} messages remaining in spool."); } if (remainingCount > 90) { LogWarn(string.Format("Warning. Spool has {0} buffered messages.", remainingCount)); } } } else { int remainingCount = Queue.Count; if (remainingCount > 0) { LogWarn($"Connection Bad or Error. {Queue.Count} messages remaining in spool."); } await Task.Delay(Convert.ToInt32(AmqpCFXEndpoint.ReconnectInterval.Value.TotalMilliseconds)); } } lock (this) { isProcessing = false; } await Task.Yield(); }
/// <summary> /// Performs a direct, point-to-point request/response transaction with another CFX Endpoint. /// </summary> /// <param name="targetUri">The network address of the Endpoint to which the request will be sent. /// May use amqp:// or amqps:// topic (amqps for secure communications). /// May also include user information (for authentication), as well as a custom TCP port. /// </param> /// <param name="request">A CFX envelope containing the request.</param> /// <returns>A CFX envelope containing the response from the Endpoint.</returns> public CFXEnvelope ExecuteRequest(string targetUri, CFXEnvelope request) { CFXEnvelope response = null; Connection reqConn = null; Session reqSession = null; ReceiverLink receiver = null; SenderLink sender = null; Exception ex = null; Uri targetAddress = new Uri(targetUri); CurrentRequestTargetUri = targetAddress; try { if (string.IsNullOrWhiteSpace(request.RequestID)) { request.RequestID = "REQUEST-" + Guid.NewGuid().ToString(); } Message req = AmqpUtilities.MessageFromEnvelope(request, UseCompression.Value); req.Properties.MessageId = "command-request"; req.Properties.ReplyTo = CFXHandle; req.ApplicationProperties = new ApplicationProperties(); req.ApplicationProperties["offset"] = 1; Task.Run(() => { try { ConnectionFactory factory = new ConnectionFactory(); if (targetAddress.Scheme.ToLower() == "amqps") { factory.SSL.RemoteCertificateValidationCallback = ValidateRequestServerCertificate; factory.SASL.Profile = SaslProfile.External; } if (string.IsNullOrWhiteSpace(targetAddress.UserInfo)) { factory.SASL.Profile = SaslProfile.Anonymous; } reqConn = factory.CreateAsync(new Address(targetAddress.ToString())).Result; //reqConn = new Connection(new Address(targetAddress.ToString())); reqSession = new Session(reqConn); Attach recvAttach = new Attach() { Source = new Source() { Address = request.Target }, Target = new Target() { Address = CFXHandle } }; receiver = new ReceiverLink(reqSession, "request-receiver", recvAttach, null); receiver.Start(300); sender = new SenderLink(reqSession, CFXHandle, request.Target); sender.Send(req); Message resp = receiver.Receive(RequestTimeout.Value); if (resp != null) { receiver.Accept(resp); response = AmqpUtilities.EnvelopeFromMessage(resp); } else { throw new TimeoutException("A response was not received from target CFX endpoint in the alloted time."); } } catch (Exception ex3) { AppLog.Error(ex3); ex = ex3; } }).Wait(); } catch (Exception ex2) { AppLog.Error(ex2); if (ex == null) { ex = ex2; } } finally { if (receiver != null && !receiver.IsClosed) { receiver.CloseAsync(); } if (sender != null && !sender.IsClosed) { sender.CloseAsync(); } if (reqSession != null && !reqSession.IsClosed) { reqSession.CloseAsync(); } if (reqConn != null && !reqConn.IsClosed) { reqConn.CloseAsync(); } } if (ex != null) { if (ex.InnerException != null) { throw ex.InnerException; } throw ex; } return(response); }
public CFXEnvelope ExecuteRequest(string targetUri, CFXEnvelope request) { CFXEnvelope response = null; Connection reqConn = null; Session reqSession = null; ReceiverLink receiver = null; SenderLink sender = null; Exception ex = null; Uri targetAddress = new Uri(targetUri); try { if (string.IsNullOrWhiteSpace(request.RequestID)) { request.RequestID = "REQUEST-" + Guid.NewGuid().ToString(); } Message req = AmqpUtilities.MessageFromEnvelope(request, UseCompression.Value); req.Properties.MessageId = "command-request"; req.Properties.ReplyTo = CFXHandle; req.ApplicationProperties = new ApplicationProperties(); req.ApplicationProperties["offset"] = 1; Task.Run(() => { try { reqConn = new Connection(new Address(targetAddress.ToString())); reqSession = new Session(reqConn); Attach recvAttach = new Attach() { Source = new Source() { Address = CFXHandle }, Target = new Target() { Address = request.Target } }; receiver = new ReceiverLink(reqSession, "request-receiver", recvAttach, null); receiver.Start(300); sender = new SenderLink(reqSession, CFXHandle, request.Target); sender.Send(req); Message resp = receiver.Receive(RequestTimeout.Value); if (resp != null) { receiver.Accept(resp); response = AmqpUtilities.EnvelopeFromMessage(resp); } else { throw new TimeoutException("A response was not received from target CFX endpoint in the alloted time."); } } catch (Exception ex3) { AppLog.Error(ex3); ex = ex3; } }).Wait(); } catch (Exception ex2) { AppLog.Error(ex2); if (ex == null) { ex = ex2; } } finally { if (receiver != null && !receiver.IsClosed) { receiver.Close(); } if (sender != null && !sender.IsClosed) { sender.Close(); } if (reqSession != null && !reqSession.IsClosed) { reqSession.Close(); } if (reqConn != null && !reqConn.IsClosed) { reqConn.Close(); } } if (ex != null) { throw ex; } return(response); }