Alessandro De Rossi
Alessandro De Rossi

Reputation: 1

Await netmq response asynchronously

I have a software consisting in one server and multiple clients. For communications I am using NetMQ, with a Publisher and Router sockets on the server, Subscriber and Dealer on the clients. Everything is done with the poller, allowing me to operate asynchronously. Now I am facing the need to make a request and getting the response on the same call. Request/Response pattern are for this case, but when I await for the response, the thread freeze until the server send a response.

Question: is there a way to make the request and await until the response from the server arrives (or throw a timeout error) asynchronously? Like a web request, but with the sockets.

I tried creating these functions:

public static string SendRequest(string message)
{
    requestSocket.SendFrame(message);
    response = requestSocket.ReceiveFrameString();
    return response;
}

public static async Task<string> RequestTask(string message)
{
   requestSocket.SendFrame(message);
   var messageFromServer = await requestSocket.ReceiveFrameStringAsync();
   return messageFromServer.Item1;
}

If I call the function SendRequest from a button event, the UI thread hangs until the server send a response, but if I call the RequestTask function in an async button click event like this

private async void btnSendToRequest_Click(object sender, RoutedEventArgs e)
{
   var response = await NetMQClient.RequestTask(txbSendToRequest.Text);
}

I get an Exception

System.InvalidOperationException: 'NetMQRuntime must be created before calling async functions'

Upvotes: 0

Views: 918

Answers (2)

Afsal
Afsal

Reputation: 130

Hope you got the Solution from the original Docs

To use async/await feature you need to create a NetMQRuntime. you need to run ClientAsync() inside the created NetMQRuntime like this :

using (var runtime = new NetMQRuntime())
{
runtime.Run(ClientAsync());
}

Upvotes: 0

ldvtlucas
ldvtlucas

Reputation: 37

As I was reading from the docs, you should be initializing the client like so:

async Task ClientAsync()
{
    using (var client = new DealerSocket("inproc://async"))
    {
        for (int i = 0; i < 1000; i++)
        {
            client.SendFrame("Hello");
            var (message, more) = await client.ReceiveFrameStringAsync();

            // TODO: process reply

            await Task.Delay(100);
        }
    }
}

Here is the link to the doc section

Upvotes: 0

Related Questions