{"id":3061,"date":"2011-02-25T11:47:08","date_gmt":"2011-02-25T10:47:08","guid":{"rendered":"http:\/\/blog.jteam.nl\/2011\/02\/25\/getting-gwt-to-work-with-servlet-3-async-requests\/"},"modified":"2011-02-25T11:47:08","modified_gmt":"2011-02-25T10:47:08","slug":"getting-gwt-to-work-with-servlet-3-async-requests","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/","title":{"rendered":"Getting GWT to work with Servlet 3 Async Requests"},"content":{"rendered":"<p>For one of our projects, we use a GWT client that needs to be updated in near-real time (&lt; 1 second delay) when something relevant happens on the server. There are multiple ways of doing it, but I tried to get it working with the new Servlet 3 feature: Asynchronous Http Request handling.<\/p>\n<p>Read on to find out how I got it done.<\/p>\n<p><!--more--><\/p>\n<h2>Servlet 3 and Asynchronous Requests<\/h2>\n<p>Until now requests to servlets require the calling thread to block until the whole response has been written to the HttpServletResponse. Once the method returns, the servlet container will commit the contents written to the response and send it to the client.<\/p>\n<p>With Servlet 3, that isn\u2019t necessary anymore. You can mark a request as asynchronous by calling the \u201cstartAsync()\u201d method on the request. This tells the servlet container not to finish the request once the method returns, but to wait for a \u201ccomplete\u201d invocation.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">protected void doGet(final HttpServletRequest req,\n                    final HttpServletResponse resp) throws ... {\n    final AsyncContext ctx = req.startAsync();\n    someAsyncProcess.run(new Runnable(){\n        @Override\n        public void run() {\n            \/\/ do stuff\n            ctx.complete();\n        }\n    });\n}<\/pre>\n<p>The main advantage here is that when a request needs to wait for data, the thread can be use for something else. Given that sockets are a lot cheaper resource than threads, it is a good way to deal with a large number of requests.<\/p>\n<h2>Our use case<\/h2>\n<p>Our application uses a GWT front-end. One of the components in this frontend needs to be continuously updated with events from the server. Initially, we implemented this using a poller, that polls the server for new events each 500ms. Although the polling action on the server is quite cheap (it checks a component available in memory), setting up a request just to return a \u201cthere is no new information\u201d response each time takes up valuable server and network resources.<\/p>\n<p>We wanted a form of long polling, where a \u201cno data available\u201d is not sent to the user. Instead, it would wait for data to become available and send it to the front-end. Until servlet 3, this required either 3rd party components or a blocking thread. We didn\u2019t want either of them.<\/p>\n<p>What we can do with Servlet 3 Async is return the thread, and only use a thread (from a thread pool) to send the client\u2019s response when it is ready. Not only is it a lot cheaper than the short polling, it also responds faster as data is sent to the client immediately when it is available.<\/p>\n<h2>Getting it to work in GWT<\/h2>\n<p>Client-server communication in GWT is done using RPC. You need to define 2 interfaces: MyServiceName and MyServiceNameAsync. The first is used on the server side to implement the service operation, the second is used client side, as javascript requires asynchronous execution to prevent the browser from hanging.<\/p>\n<p>Let me put it simply: I want to implement the Async interface on the server. But GWT doesn\u2019t support that. If forces you into the direct-response model of servlet 2.x.<\/p>\n<p>So, I hacked my way through GWT\u2019s RemoteServiceServlet and created a variant that allows you to implement the Async service interface instead. The result can be found in <a href=\"\/wp-content\/uploads\/2011\/02\/RemoteServiceAsyncServlet.zip\">this<\/a> class. It\u2019s not really clean code yet, but it does the job.<\/p>\n<p>If you want to use this class to create you need to create a Service implementation that extends this class, and implements the YourServiceNameAsync interface. You still need the YourServiceName interface, as GWT uses it to find method names and return types for serialization. Use the Callback to notify the container that the return value (or exception) is ready to be sent to the client.<\/p>\n<p>Don\u2019t forget to add the &lt;async-supported&gt;true&lt;\/async-supported&gt; tag in your web.xml servlet definition. If you forget that (which I did), you\u2019ll get exceptions stating that Async support is not available.<\/p>\n<p>Then it\u2019s time to run. Make sure you run it in a container that supports the servlet 3 spec, such as Tomcat 7. The GWT SDK comes with a Jetty runner that doesn\u2019t support Servlet 3. They also included the servlet 2.5 API in there. Just make sure Servlet 3 API is on the classpath before the 2.5 version, and you should be fine.<\/p>\n<h2>Conclusion<\/h2>\n<p>In the end, I got it all working, and the client is very responsive when the server send a notification. I certainly hope Google decides to provide their own implementation of this servlet. If you have any questions or other ideas, don\u2019t hesitate to drop a comment or <a href=\"http:\/\/www.jteam.nl\/contact.html\" target=\"_blank\" rel=\"noopener\">contact<\/a> me through JTeam.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For one of our projects, we use a GWT client that needs to be updated in near-real time (&lt; 1 second delay) when something relevant happens on the server. There are multiple ways of doing it, but I tried to get it working with the new Servlet 3 feature: Asynchronous Http Request handling. Read on [&hellip;]<\/p>\n","protected":false},"author":14,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[123,31,10],"tags":[230,136,122,231],"class_list":["post-3061","post","type-post","status-publish","format-standard","hentry","category-gwt","category-java","category-development","tag-asynchronous","tag-google-web-toolkit","tag-gwt","tag-servlet-3"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Getting GWT to work with Servlet 3 Async Requests - Trifork Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Getting GWT to work with Servlet 3 Async Requests - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"For one of our projects, we use a GWT client that needs to be updated in near-real time (&lt; 1 second delay) when something relevant happens on the server. There are multiple ways of doing it, but I tried to get it working with the new Servlet 3 feature: Asynchronous Http Request handling. Read on [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2011-02-25T10:47:08+00:00\" \/>\n<meta name=\"author\" content=\"Allard Buijze\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Allard Buijze\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/\",\"url\":\"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/\",\"name\":\"Getting GWT to work with Servlet 3 Async Requests - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"datePublished\":\"2011-02-25T10:47:08+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/a4e232a11dc57a2c4c581956ce6fde63\"},\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Getting GWT to work with Servlet 3 Async Requests\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/a4e232a11dc57a2c4c581956ce6fde63\",\"name\":\"Allard Buijze\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3e7130b2465615e105b1addd400a3f06?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3e7130b2465615e105b1addd400a3f06?s=96&d=mm&r=g\",\"caption\":\"Allard Buijze\"},\"description\":\"Allard (@allardbz) is CTO of Trifork Amsterdam and founder of Axon Framework. He is a trainer and speaker at conferences on topics related to scalable architecture and domain driven design. He strongly believes that good craftsmanship can only be achieved through continuous and intensive exchange of experience with others. The last years, he has been investigating and applying CQRS to a number of projects. As a result, he created the Axon Framework, an open source Java framework that helps developers create scalable and extensible applications. Axon has a growing community and has already been successfully introduced in several high-profile projects around the world.\",\"url\":\"https:\/\/trifork.nl\/blog\/author\/allard\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Getting GWT to work with Servlet 3 Async Requests - Trifork Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/","og_locale":"en_US","og_type":"article","og_title":"Getting GWT to work with Servlet 3 Async Requests - Trifork Blog","og_description":"For one of our projects, we use a GWT client that needs to be updated in near-real time (&lt; 1 second delay) when something relevant happens on the server. There are multiple ways of doing it, but I tried to get it working with the new Servlet 3 feature: Asynchronous Http Request handling. Read on [&hellip;]","og_url":"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/","og_site_name":"Trifork Blog","article_published_time":"2011-02-25T10:47:08+00:00","author":"Allard Buijze","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Allard Buijze","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/","url":"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/","name":"Getting GWT to work with Servlet 3 Async Requests - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"datePublished":"2011-02-25T10:47:08+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/a4e232a11dc57a2c4c581956ce6fde63"},"breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/getting-gwt-to-work-with-servlet-3-async-requests\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"Getting GWT to work with Servlet 3 Async Requests"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/a4e232a11dc57a2c4c581956ce6fde63","name":"Allard Buijze","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/3e7130b2465615e105b1addd400a3f06?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3e7130b2465615e105b1addd400a3f06?s=96&d=mm&r=g","caption":"Allard Buijze"},"description":"Allard (@allardbz) is CTO of Trifork Amsterdam and founder of Axon Framework. He is a trainer and speaker at conferences on topics related to scalable architecture and domain driven design. He strongly believes that good craftsmanship can only be achieved through continuous and intensive exchange of experience with others. The last years, he has been investigating and applying CQRS to a number of projects. As a result, he created the Axon Framework, an open source Java framework that helps developers create scalable and extensible applications. Axon has a growing community and has already been successfully introduced in several high-profile projects around the world.","url":"https:\/\/trifork.nl\/blog\/author\/allard\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/3061","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=3061"}],"version-history":[{"count":0,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/3061\/revisions"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=3061"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=3061"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=3061"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}