• Skip to main content
  • Skip to primary sidebar
  • Home
  • About
  • Subscribe BMA
  • Contact Us!

Be My Aficionado

Inspire Affection

You are here: Home / Programming / Long Polling Implementation With Java and Spring Boot

Long Polling Implementation With Java and Spring Boot11 min read

May 14, 2020 by Varun Shrivastava 11 Comments

Long polling is a concept that was being used aggressively in the past. It was the technique that made web feel like real-time.

I think a little history would help you to understand better.

Topics Covered

  • The Brief History Of Internet
    • Era After Javascript
  • The Birth Of Long Polling
      • Short Polling Technique
      • Long Polling
  • Implementation Of Long Polling Technique
    • Project Directory Structure
    • LongPollingController
    • KeepPolling Method
    • LongPollingControllerTest
  • Conclusion

The Brief History Of Internet

If you are old enough then you would know that web in its early days was very boring. And by boring I mean static, no moving parts.

It simply worked synchronously in a uni-directional way under the HTTP Request/Response model.

Unidirectional Request/Response paradigm
Request Response Model

In this model, the client requests server to send a particular webpage. And the server sends it to the client. The story ends there.

If the client wants another page, it will send another request for the page’s data and the server will send the requested data as an HTTP Response.

There is nothing fancy. Very simple, very monotonous.

So in the early days of the web, HTTP made sense as a simple request-response protocol because it was designed to serve the documents from the server on the client’s demand. That document would then contain the links (hyperlinks) to other documents.

There was nothing like javascript. It was all HTML.

Era After Javascript

Javascript was born in the year 1995 when Netscape Communications hired Brendan Eich to implement scripting capabilities in Netscape Navigator, and over a ten-day period, the JavaScript language was born.

How much can you do with a language that was built in 10 days – Well nothing much. It was only used for complementing the HTML… like providing form validation and a lightweight insertion of dynamic HTML.

But this gave a whole new way to the world of web development. It was moving towards the era of dynamic from static. The web was no more static, it found the ability to change itself dynamically.

In the next 5 years, when the browser war heated up, Microsoft gave birth to the XMLHttpRequest object. This, however, was only supported by Microsoft Internet Explorer.

It was the year 2006 when the World Wide Web Consortium published a working specification of the XMLHttpRequest object on April 5, 2006. This gave the power to web developers – They can now send asynchronous requests to get data from the server and change the parts of DOM with the new data. No need to load the entire page anymore.

This made the web more exciting and less monotonous.

This was the time in the history where a real-time Chat Application became real. It was implemented using a Long Polling mechanism.

The Birth Of Long Polling

Long polling was born out of necessity. Before long polling people used to work with short polling techniques.

The entire web works on the Request/Response protocol so there was no way for server to push the message to the client. It was always the client who has to request the data.

Short Polling Technique

In short polling technique, the client continuously sends a request to the server and ask for the new data. If there is no new data server sends back the empty response, but if the server has got the new data then it sends back the data.

Short Polling Technique
Short Polling

This seems to be a working model but it has several drawbacks.

The obvious drawback was the frequency of chat between client and server. The clients will continue sending an HTTP request to the server.

Processing HTTP requests are costly. There is a lot of processing involved.

  • every time a new connection needs to be established.
  • the HTTP headers must be parsed
  • a query for new data must be performed
  • and a response (usually with no new data to offer) must be generated and delivered.
  • The connection must then be closed, and any resources must be cleaned up.

Now imagine the above steps taking place for every single request coming into the server from every single client. There is a lot of resources that are getting wasted for doing no work (practically).

I tried hard to show the processing, chaos and data transfer involved in the image below (:p).

Short polling with multiple clients
Short polling with multiple clients

So, how can we improve the above nasty scenario?

A simple solution was a long polling technique.

Long Polling

The solution seems to be pretty simple. Make the connection once and let them wait for as long as possible. So that in the meanwhile if any new data comes to the server, the server can directly give the response back. This way we can definitely reduce the number of requests and response cycles involved.

Let’s understand the scenario with the help of an image.

Long Polling Technique
Long Polling

Here, every client sends the request to the server. Server checks for the new data, if the data is not available then it does not send back the response immediately; rather, it waits for sometime before sending the response. And in the meantime, if the data is available, it sends back the response with the data.

By implementing Long polling technique, we can easily reduce the number of request and response cycles that was taking place before (short polling).

In short, Long polling a technique to hang the connection between client and server until the data is available.

You must be thinking about the connection timeout issue?

There are multiple ways to deal with this situation:

  • Wait till the connection times out, and send a new request again.
  • Use Keep-Alive header when listening for a response – With long polling, the client may be configured to allow for a longer timeout period (via a Keep-Alive header) when listening for a response – something that would usually be avoided seeing as the timeout period is generally used to indicate problems communicating with the server.
  • Maintain the state of the client’s request and continue redirecting the client to a /poll endpoint after a certain duration of time.

The Long Polling technique is a lot better than short polling but still, it is resource consuming. In the next article, I will write about WebSockets and see how WebSockets is a much better solution when it comes to real-time applications.

Now, let’s jump to the implementation part of Long polling with Java using Spring boot framework.

Implementation Of Long Polling Technique

The idea of writing this article came from a technical problem that I faced while working on one of the client’s project.

The problem was that the task that was executed in a request was taking too much time for the completion. Because of this long wait, the client was facing the connection timeout issue.

Websockets solution was not possible because the client is not in our control. There was something needed to be done from our end in order to make it work.

I thought of using the Keep-Alive header but as I said it is not the right thing to do because something that would usually be avoided seeing as the timeout period is generally used to indicate problems communicating with the server. This alerts the monitoring systems that something is wrong.

The solution that seemed to be feasible was a continuous redirection to the polling endpoint with the unique id for the task.

That was a bit complex but here I’m going to give you the glimpse of long polling with a simple Real-time Chatting API.

Project Directory Structure

Project's Directory Structure
Project’s Directory Structure

The only thing you should focus here is the LongPollingController.java and LongPollingControllerTest.java.

LongPollingController

Let’s look into the LongPollingController.java code:

First, take a look at the /sendMessage endpoint:

private static final List<CustomMessage> messageStore = new ArrayList<>();
 
    @PostMapping("/sendMessage")
    public ResponseEntity<List<CustomMessage>> saveMessage(@RequestBody CustomMessage message) {
        log.debug(message);
        message.setId(messageStore.size() + 1);
        messageStore.add(message);
        return ResponseEntity.ok(messageStore);
    }

It is a very generic endpoint, it takes in the input from a POST request and stores the message in the message store. For simplicity, I’m storing the messages in the memory using a ArrayList instance.

The message-id is the unique key with which we will identify what needs to be sent back in the response.

Suppose you sent a new post request, the message-id will be +1 of the last message.

Next part of this implementation is the /getMessages endpoint:

    @GetMapping("/getMessages")
    public ResponseEntity<List<CustomMessage>> getMessage(GetMessage input) throws InterruptedException {
        if (lastStoredMessage().isPresent() && lastStoredMessage().get().getId() > input.getId()) {
            List<CustomMessage> output = new ArrayList<>();
            for (int index = input.getId(); index < messageStore.size(); index++) {
                output.add(messageStore.get(index));
            }
            return ResponseEntity.ok(output);
        }
 
        return keepPolling(input);
    }

The method expects two parameters:

  • id – This is the message-id after which it wants the messages.
  • to – This field represents the person for which the message was intended. So, the client wants all the messages that were sent to him.

The first part of the logic checks, if the last message id stored in the messageStore is greater than the asked id. If it is greater then it means there is a new message available since the client last checked. Therefore, create the output with the messages that have been received after that index and sent it back in response.

KeepPolling Method

Another part of the logic is the one that stalls the connection.

    private ResponseEntity<List<CustomMessage>> keepPolling(GetMessage input) throws InterruptedException {
        Thread.sleep(5000);
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(URI.create("/getMessages?id=" + input.getId() + "&to=" + input.getTo()));
        return new ResponseEntity<>(headers, HttpStatus.TEMPORARY_REDIRECT);
    }

If there is no new message in the store, simply wait for 5 seconds (halt the connection) and then redirect it back to the /getMessages endpoint. If the message is available by then send back the response with the data otherwise repeat the process.

Sure you can make it more efficient by checking it once again before sending back the temporary redirect response but you got the idea, right?

And the main reason I’m sending back a redirect header response is that if I stall the connection for too long then it will time out. And I don’t want that. I want the client to keep coming back until I have served it with the data.

This implementation was exactly suited for the kind of situation I was in during my project, but you can also take the learnings from this approach and bend it and make it work for yourself.

That said, if you want to make a chatting application, go with the WebSockets. That is the most efficient and modern ways of creating real-time applications.

LongPollingControllerTest

I also want you to take a look at the test class to understand the implementation of the API.

Here I have created one asynchronous thread that will act as a sender. It will wait for 10 seconds and send the message that will be addressed for a user named Bar.

And the receiver will send a get request with the id of the current messages it has i.e. 0 for the first time. And you will see that the connection will be established for 10 seconds. And as soon as the sender sends the message, the receiver will get the response.

Conclusion

This was a very simple and straightforward implementation of the Long Polling technique.

There is a lot of complex stuff that needs to be taken care, such as maintaining the state of the client’s request. The data that needs to be sent to each client and maintaining the concurrent connections at once.

This technique is fairly intuitive to understand and could result productive in many applications.

That said, I would not want you to implement Long Polling in any real-time application that you are building now. There are WebSockets available and they are very feasible and efficient when it comes to bi-directional communication. In short, use WebSockets to build real-time applications.

Don’t forget to comment and subscribe. The next article will be sent directly to your inbox.

Share this:

  • Click to share on Facebook (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Twitter (Opens in new window)
  • Click to share on Pinterest (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • More
  • Click to print (Opens in new window)
  • Click to share on Tumblr (Opens in new window)
  • Click to share on Pocket (Opens in new window)
  • Click to share on Telegram (Opens in new window)
  • Click to share on WhatsApp (Opens in new window)
  • Click to share on Skype (Opens in new window)
  • Click to email this to a friend (Opens in new window)

Filed Under: Programming Tagged With: java, long polling, persistent connection, spring, web

Reader Interactions

Comments

  1. Sathya Janatharni says

    March 1, 2021 at 7:44 am

    Nice article Varun.

    I am trying to use long poll for monitoring the status of an incident ticket raised in ticket Management Tool. Requirement is to poll the ticket api until the status reached COMPLETED.

    Could you please let me know as how to deal the below criteria as I am not sure to modify the input.getId() here as what could be the value of this input.getId(). Any help is much appreciated.

    if (lastStoredMessage().isPresent() && lastStoredMessage().get().getId() > input.getId()) {}

    Thanks,
    Dev

    Reply
    • Varun Shrivastava says

      March 1, 2021 at 2:28 pm

      Hey Sathya,
      Here input.getId() is the message-id that is last received by the client. So, the client will send the last received message-id and expect a response with all the messages that have come to the server after that id.

      In this example, I’ve used message id in increasing order that is message#1 will have id 1, message#2 will have id 2 and so on. Therefore with below logic,

      if (lastStoredMessage().get().getId() > input.getId())
      {
          for (int index = input.getId(); index < messageStore.size(); index++) 
          {
              output.add(messageStore.get(index));
          }
      }
      

      The above code fetches all the messages that have come after the last user request.

      In the real world scenario, the messages will be fetched from the database based on the last requested timestamp.

      I hope it answers your query. Do let me know if you have any further doubts?

      Thanks

      Reply
  2. Reda Rebouh says

    February 18, 2021 at 4:05 pm

    Hi Varun,

    Thank you for this article, it was very clear, and I could implement the long poling in the server side using this technique. But I have a timeout issue. I am also using a python client, and trying to maintain connection but after 30 redirects I get an error (TooManyRedirects). Is something I can do to keepPolling method (before redirection) in order to prevent this error ? I tried many possibilities but non of them works. Thank you !

    Reply
    • Varun Shrivastava says

      February 18, 2021 at 9:25 pm

      Hey Reda, thanks for the comment.

      I think you will have to find a way to configure the max redirect settings on the python client. Usually there is some defaults (in your case it’s 30) but that can be overridden.

      Try googling on how to set max redirect in the python client that you are using.

      Reply
  3. Amir Kadoorie says

    October 25, 2020 at 2:54 pm

    Hello Varun, your article well explained and helped me a lot during my research for solving a timeout issue during a long processing request. Though, during my research for finding a solution, I also found the following Spring boot’s mechanism that sounds like solving similar issue:
    https://www.baeldung.com/spring-deferred-result
    My question to you is whether you encountered ‘DeferredResult’ and you can point the difference between it and the approach that you described in the article. Thank you

    Reply
    • Varun Shrivastava says

      December 18, 2020 at 7:20 pm

      Apologies for the late reply.

      To answer your question – I’ve done most of the things that Spring does it for you when you return the deferred result from the method.

      But the reason I did it this way is to tackle the problem of long stale connections which could be a security vulnerability as well. By default, no web server allows a connection to persist for more than a few minutes and after that, it terminates them saying connection timeout. In that case, you would lose the state of the request. So, in my approach, I redirect the request before the connection times out. By doing that way, a new request is created every time. Now to maintain the state of the request I needed to manage the threads myself. And that’s how I did it,

      I hope I answered your question. And if not then please do revert back.

      Reply
  4. Bhagwati Malav says

    October 1, 2020 at 4:16 pm

    Well explained thanks.

    Reply
    • Varun Shrivastava says

      December 18, 2020 at 7:00 pm

      You’re welcome Bhagwati 🙂

      Reply
  5. Devansh says

    May 31, 2020 at 9:26 pm

    can we depend on Spring WebFlux for the same ?

    Reply
    • Varun Shrivastava says

      June 2, 2020 at 3:47 pm

      I doubt that. Since, Webflux is based on a reactive approach in which all the clients requests are served in a non-blocking fashion. And since Long Polling is a way to hold on to the client’s connection until the data is available, so Webflux is not the right thing for that.

      But if you need a two way duplex connection then I would recommend you to go with the websockets. Webflux can be integrated with websockets for a two way connection.

      Reply
    • Varun Shrivastava says

      June 2, 2020 at 3:47 pm

      You can read more on it here – https://developer.okta.com/blog/2018/09/25/spring-webflux-websockets-react

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Featured Posts

Best Web Hoster: HostGator VS DreamHost [Web Hosting Comparison]

October 4, 2017 By Varun Shrivastava Leave a Comment

Top 5 Best Seller Books Every Budding Entrepreneur Must Read

September 10, 2017 By Varun Shrivastava 9 Comments

How To Setup Your MacOS Machine For Any Development

October 6, 2019 By Varun Shrivastava Leave a Comment

HACK-Free 1 year Amazon Prime Membership

August 10, 2017 By Varun Shrivastava 28 Comments

How to Remove Android Malware from Devices?

April 23, 2019 By Rodney Amos Leave a Comment

Latest Posts

  • 3 Best Laptops (Mid-Range) For Every Use Case In India
  • Distributed System Architectural Patterns
  • The Power of being in the Present
  • Basic Calculator Leetcode Problem Using Object-Oriented Programming In Java
  • Study Abroad Destinations : Research and Review

Categories

  • Blogging (103)
  • Cooking (11)
  • Fashion (7)
  • Finance & Money (12)
  • Programming (51)
  • Reviews (4)
  • Technology (22)
  • Travelling (4)
  • Tutorials (12)
  • Web Hosting (8)
  • Wordpress N SEO (19)

Follow us on facebook

Follow us on facebook

Grab the Deal Now!

Hostgator Starting @$3.95/mo

DigitalOcean Free Credits

Trending

Affordable Hosting amazon aoc-2020 bad luck believe in yourself best database earn money blogging education experience fashion finance Financial Freedom food friends goals google india indian cuisine indian education system java javascript life life changing love make money microservices motivation oops poor education system principles of microservices problem-solving programmer programming reality search engines seo SSD Hosting success technology tips top 5 web web developer wordpress

Copyright © 2021 · BeMyAficionado by Varun Shrivastava · WordPress

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.