0

Premise: We have groovy scripts that execute every minute. I want one of those scripts to open an HTTP client, and poll a service bus queue / topic for messages. I have my rest client code working an getting messages from the service bus queue. I can do a "Get" every 5 seconds, and wireshark shows that it's reusing the same TCP connection which is better than I expected, but its still not ideal.

Goal: I would like to make this http client do "long polling", for efficiency and to achieve actual real-time processing. It seems to be more complicated than I anticipated.

Problem: When I do a "Delete" call to read message from a service bus queue, it immediately returns "HTTP/1.1 204 No Content", and the connection closes. I set a timeout on the client, but I don't think that matters.

Here's the article that shows service bus says it's supports long polling, which I imagine is the hard part. Azure Service Bus Queues

I feel that I don't understand something fundamental about how to implement long polling in code. My understanding is that when there is no data in the queue, it's supposed to delay the response until data exists, or until my client eventually times out waiting (which lets me set my own disconnect/reconnect interval). I don't even care about blocking/nonblocking etc, because the script execution is already spreadout into a threadpool, and will be terminated forcibly and all that.

Any help is greatly appreciated.

Peter Pan
  • 23,476
  • 4
  • 25
  • 43
solvingJ
  • 1,321
  • 1
  • 19
  • 30

2 Answers2

1

The correct and simple answer is that adding the following to the end of an Azure REST API URL (with service bus) is the way to implements long-polling with that service: ?timeout=60 , where 60 tells azure to wait 60 seconds before responding with no-data. So, your application can check for data every 60 seconds, with an internal timeout of 60 seconds on each HTTP request. This will hold the TCP connection open for that timeframe, waiting for an HTTP response.

solvingJ
  • 1,321
  • 1
  • 19
  • 30
0

For understanding long polling, I recommend you can learn the entry Comet of Wiki https://en.wikipedia.org/wiki/Comet_(programming). And there is an answered thread (Long polling in java) explained the mechanism of the HttpURLConnection Class support long polling in Java.

As I know, a simple way in Java Client instead of HttpURLConnection is using the client library of CometD. You can refer to the section Client Library of its offical document https://docs.cometd.org/current/reference/#_java_client to learn how to implement the long polling client in Java. You can download the library at https://download.cometd.org/.

The sample code from the offical document:

// Create (and eventually set up) Jetty's HttpClient:
HttpClient httpClient = new HttpClient();
httpClient.start();

// Prepare the transport
Map<String, Object> options = new HashMap<String, Object>();
ClientTransport transport = new LongPollingTransport(options, httpClient);

// Create the BayeuxClient
ClientSession client = new BayeuxClient("http://localhost:8080/cometd", transport);

// Here set up the BayeuxClient, for example:
// client.getChannel(Channel.META_CONNECT).addListener(new ClientSessionChannel.MessageListener() { 
    public void onMessage(ClientSessionChannel channel, Message message) {
        if (message.isSuccessful()) {
            // Here handshake is successful
        }
    }
});
client.handshake();

Note: There are two REST API of Azure Service Bus for getting messaging entity(s) Get Entity https://msdn.microsoft.com/en-us/library/azure/hh780754.aspx and Entities Discovery https://msdn.microsoft.com/en-us/library/azure/hh780782.aspx. You need to delete the used messaging entity manually thru the Delete Entity REST API. Requesting all of these REST API first require an access_token thru the post request the Request a Token from ACS API for secure access.

Community
  • 1
  • 1
Peter Pan
  • 23,476
  • 4
  • 25
  • 43
  • Thanks for trying to help Peter. – solvingJ Dec 18 '15 at 18:26
  • I see you suggest delete entity with access token. In my post, I explained I am already doing a delete with access token. My question is about what happens next. I'm getting back a 204 (no data) response immediately after I do delete. This seems wrong. Can you offer explanation why Service Bus sending back 204 instead of holding the connection until there is data? I assume I'm missing something, and it's not a bug with Azure. Excerpt from a good document: "Long polling is push technology, where the server does not respond immediately but responds when data is available." – solvingJ Dec 18 '15 at 18:38
  • @JerryW. I reviewed some docs again. It seems to be that the long polling only supported by the dotNet Client. **Not all features are available to REST clients.** Please see the section `Features exposed using both the REST client and the .NET managed API` of the doc https://msdn.microsoft.com/en-us/library/azure/hh780771.aspx. – Peter Pan Jan 07 '16 at 06:11
  • Thanks again Peter. A few followup questions... 1) I don't see long polling mentioned specifically in the matrix. 2) did you find some documentation that states that.. 3) I think the difference in the library vs rest is that the library uses AMQP and REST uses HTTP, which would better explain why a difference in supported features. If So, long-polling isn't even relevant to AMQP. If I'm wrong. then it still holds true that anything they can do over HTTP / REST with .NET, we can do over HTTP/REST in any lang. Also, Long-Polling is HTTP thing, should be universal. – solvingJ Jan 08 '16 at 14:55
  • @JerryW. Thanks for your feedback. Be sure that there not long polling mentioned specifically in the matrix, but the REST API not support `Session Receiver`. For explaining long polling, the offical doc https://azure.microsoft.com/en-us/documentation/articles/service-bus-pricing-billing/#faq said, "Receiving events with HTTP using a timeout greater than zero, sometimes called "long polling," generates brokered connection charges." You can set the timeout for REST API at https://msdn.microsoft.com/en-us/library/azure/hh780770.aspx. But I think it is not a defined strictly HTTP long polling. – Peter Pan Jan 11 '16 at 10:22
  • Thanks again peter. The correct and simple answer is that adding the following to the end of an Azure REST API URL (with service bus) is the way to implements long-polling with that service: ?timeout=60 , where 60 tells azure to wait 60 seconds before responding with no-data. So, your application can check for data every 60 seconds, with an internal timeout of 60 seconds on each HTTP request. This will hold the TCP connection open for that timeframe, waiting for an HTTP response. – solvingJ Jan 12 '16 at 15:44
  • @JerryW. Thanks for your share. If possible, I also recommend you can use AMQP in Java. The AMQP protocol is more efficient than HTTP. – Peter Pan Jan 13 '16 at 12:03