using System;
using NetMQ.Core;
namespace NetMQ.Sockets
{
///
/// A RequestSocket is a NetMQSocket intended to be used as the Request part of the Request-Response pattern.
/// This is generally paired with a ResponseSocket.
///
public class RequestSocket : NetMQSocket
{
///
/// Create a new RequestSocket and attach socket to zero or more endpoints.
///
/// List of NetMQ endpoints, separated by commas and prefixed by '@' (to bind the socket) or '>' (to connect the socket).
/// Default action is connect (if endpoint doesn't start with '@' or '>')
/// var socket = new RequestSocket(">tcp://127.0.0.1:5555,@tcp://127.0.0.1:55556");
public RequestSocket(string? connectionString = null) : base(ZmqSocketType.Req, connectionString, DefaultAction.Connect)
{
}
///
/// Create a new RequestSocket based upon the given SocketBase.
///
/// the SocketBase to create the new socket from
internal RequestSocket(SocketBase socketHandle)
: base(socketHandle)
{
}
private enum ProgressTopic
{
Send,
Retry,
Failure,
Success
}
///
/// Try to send request message and return the response as a message, or return null if not successful
///
/// a string denoting the address to connect to
/// The request message
/// The number of times to try
/// The timeout for each request
/// Report topics: Failure, Retry, Send, Success
/// the response message, or null if not successful
public static NetMQMessage? RequestResponseMultipartMessageWithRetry(string address, NetMQMessage requestMessage,
int numTries, TimeSpan requestTimeout, PublisherSocket? progressPublisher = null)
{
var responseMessage = new NetMQMessage();
while (numTries-- > 0)
{
using (var requestSocket = new RequestSocket(address))
{
progressPublisher?.SendFrame(ProgressTopic.Send.ToString());
requestSocket.SendMultipartMessage(requestMessage);
if (requestSocket.TryReceiveMultipartMessage(requestTimeout, ref responseMessage))
{
progressPublisher?.SendFrame(ProgressTopic.Success.ToString());
return responseMessage;
}
progressPublisher?.SendFrame(ProgressTopic.Retry.ToString());
}
}
progressPublisher?.SendFrame(ProgressTopic.Failure.ToString());
return null;
}
///
/// Try to send request string and return the response string, or return null if not successful
///
/// a string denoting the address to connect to
/// The request string
/// The number of times to try
/// The timeout for each request
/// Report topics: Failure, Retry, Send, Success
/// the response message, or null if not successful
public static string? RequestResponseStringWithRetry(string address, string requestString,
int numTries, TimeSpan requestTimeout, PublisherSocket? progressPublisher = null)
{
while (numTries-- > 0)
{
using (var requestSocket = new RequestSocket(address))
{
progressPublisher?.SendFrame(ProgressTopic.Send.ToString());
requestSocket.SendFrame(requestString);
if (requestSocket.TryReceiveFrameString(requestTimeout, out string? frameString))
{
progressPublisher?.SendFrame(ProgressTopic.Success.ToString());
return frameString;
}
progressPublisher?.SendFrame(ProgressTopic.Retry.ToString());
}
}
progressPublisher?.SendFrame(ProgressTopic.Failure.ToString());
return null;
}
}
}