以`在LibGDX Gdx.net.sendHtt prequest`同步响应 [英] Synchronous responses to `Gdx.net.sendHttpRequest` in LibGDX

查看:186
本文介绍了以`在LibGDX Gdx.net.sendHtt prequest`同步响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做的LibGDX一个小游戏。我在本地保存玩家的用户名,以及在服务器上。问题是,应用程序不等待呼叫这样的在线数据库的ID未在本地保存的结果。这里的code的整个流程:

  //创建一个新的用户对象
用户的用户=新用户(名);//存储用户的在线数据库
网络服务network服务=新的网络服务();
字符串ID = networkService.saveUser(用户);//设置新生成的ID质数据库在本地对象
user.setId(ID);//本地存储用户
game.getUserService()坚持(用户)。

在此code时, ID 变量没有得到设置,因为 saveUser 函数立即返回。我怎样才能使应用程序等待网络请求的结果,所以我可以从服务器的通信效果工作?

这是code为 saveUser

 公共字符串saveUser(用户用户){
    地图<字符串,字符串>参数=新的HashMap<字符串,字符串>();
    parameters.put(行动,save_user);
    parameters.put(JSON,user.toJSON());    HTT prequest HTTPGET =新HTT prequest(HttpMethods.POST);
    httpGet.setUrl(HTTP://本地主机:8080 /置备);
    httpGet.setContent(HttpParametersUtils.convertHttpParameters(参数));    WerewolfsResponseListener responseListener =新WerewolfsResponseListener();
    Gdx.net.sendHtt prequest(HTTPGET,responseListener);
    返回responseListener.getLastResponse();
}

这是 WerewolfsResponseListener 类:

 类WerewolfsResponseListener实现了Htt $ P $ {psponseListener
    私人字符串lastResponse =;
    公共无效handleHtt presponse(HTT presponse HTT presponse){
        的System.out.println(HTT presponse.getResultAsString());
        this.lastResponse = HTT presponse.getResultAsString();
    }    公共无效失败(的Throwable t)的{
       的System.out.println(保存用户失败:+ t.getMessage());
       this.lastResponse = NULL;
    }    公共字符串使用getLastResponse(){
        返回lastResponse;
    }
}


解决方案

您所看到的不同步是 Gdx.net.sendHtt prequest 。在第二个参数的方法(你的 WerewolfsResponseListener )就要求回来就会被调用。成功/失败的方法将的的援引内联。

有处理结构类似这样的回调两种基本方法:轮询或事件

通过投票,您的游戏主循环可以检查的 responseListener 来看看它的成功或失败。 (您将需要修改当前的听众有点歧义的成功案例和空字符串)。一旦你看到一个有效的反应,然后你可以做 user.setId()和等。

使用事件那么你可以把 responseListener 回调中的 user.setId()电话,因此它将每当网络响应被执行。这是一个比较天作之合到Libgdx网的API。 (它意味着你的回应听众需要将用户参考对象。)

这是不可能为等待内联的网络呼叫返回。该Libgdx网络API(正确地)假设你不想在你的渲染线程无限期阻塞,所以它不规整为(听众将被排队作为一个Runnable,所以它可以运行最早是在下一次渲染调用)

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;
    }
}

解决方案

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).

这篇关于以`在LibGDX Gdx.net.sendHtt prequest`同步响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆