Synchronous responses to `Gdx.net.sendHttpRequest` in LibGDX

asynchronous, libgdx

Solution

The asynchrony you are seeing is from `Gdx.net.sendHttpRequest`. The methods on the second parameter (your `WerewolfsResponseListener`) will be invoked whenever the request comes back. The success/failure methods will not be invoked "inline".

There are two basic approaches for dealing with callbacks structured like this: "polling" or "events".

With polling, your main game loop could "check" the `responseListener` to see if its succeeded or failed. (You would need to modify your current listener a bit to disambiguate the success case and the empty string.) Once you see a valid response, you can then do the `user.setId()` and such.

With "events" then you can just put the `user.setId()` call inside the `responseListener` callback, so it will be executed whenever the network responds. This is a bit more of a natural fit to the Libgdx net API. (It does mean your response listener will need a reference to the `user` object.)

It is not possible to "wait" inline for the network call to return. The Libgdx network API (correctly) assumes you do not want to block indefinitely in your render thread, so its not structured for that (the listener will be queued up as a Runnable, so the earliest it can run is on the next render call).

Problem

I'm making a small game in LibGDX. I'm saving the player's username locally as well as on a server. The problem is that the application is not waiting for the result of the call so the online database's ID is not saved locally. Here's the overall flow of the code: ``` //Create a new user object User user = new User(name); //Store the user in the online database NetworkService networkService = new NetworkService(); String id = networkService.saveUser(user); //Set the newly generated dbase ID on the local object user.setId(id); //Store the user locally game.getUserService().persist(user); ``` in this code, the `id` variable is not getting set because the `saveUser` function is returning immediately. How can I make the application wait for the result of the network request so I can work with results from the server communication? This is the code for `saveUser`: ``` public String saveUser(User user) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("action", "save_user"); parameters.put("json", user.toJSON()); HttpRequest httpGet = new HttpRequest(HttpMethods.POST); httpGet.setUrl("http://localhost:8080/provisioner"); httpGet.setContent(HttpParametersUtils.convertHttpParameters(parameters)); WerewolfsResponseListener responseListener = new WerewolfsResponseListener(); Gdx.net.sendHttpRequest (httpGet, responseListener); return responseListener.getLastResponse(); } ``` This is the `WerewolfsResponseListener` class: ``` class WerewolfsResponseListener implements HttpResponseListener { private String lastResponse = ""; public void handleHttpResponse(HttpResponse httpResponse) { System.out.println(httpResponse.getResultAsString()); this.lastResponse = httpResponse.getResultAsString(); } public void failed(Throwable t) { System.out.println("Saving user failed: "+t.getMessage()); this.lastResponse = null; } public String getLastResponse() { return lastResponse; } } ```

Original source