我正在玩Play Framework(v2.2.2),我正在试图弄清楚如何暂停HTTP请求。我正在尝试在用户之间创建握手,这意味着,我希望用户A能够触发请求并等待用户B“连接”。一旦用户B连接,用户A的请求应返回一些信息(信息无关紧要;现在让我们说一些JSON)。
在我工作的另一个应用程序中,我使用continuation来实质上暂停和重放HTTP请求,所以我有这样的东西......
@Override
public JsonResponse doGet(HttpServletRequest request, HttpServletResponse response) {
Continuation reqContinuation = ContinuationSupport.getContinuation(request);
if (reqContinuation.isInitial()) {
...
reqContinuation.addContinuationListener(new ContinuationListener() {
public void onTimeout(Continuation c) {...}
public void onComplete(Continuation c) {...}
});
...
reqContinuation.suspend();
return null;
}
else {
// check results and return JsonResponse with data
}
}
...在某些时候,用户B将连接并且继续将在不同的servlet中恢复/完成。现在,我正在试图弄清楚如何在Play中执行此操作。我已经建立了自己的路线......
GET /test controllers.TestApp.test()
......我有我的行动......
public static Promise<Result> test() {
Promise<JsonResponse> promise = Promise.promise(new Function0<JsonResponse>() {
public JsonResponse apply() {
// what do I do now...?
// I need to wait for user B to connect
}
});
return promise.map(new Function<JsonResponse, Result>() {
public Result apply(JsonResponse json) {
return ok(json);
}
});
}
我很难理解如何构建我的承诺。基本上,我需要告诉用户A“嘿,你在等待用户B,所以这是一个承诺,用户B最终将连接到你,否则我会告诉你什么时候你不必再等了”
如何暂停请求以便我可以返回用户B连接的承诺?如何等待用户B连接?
答案 0 :(得分:2)
您需要创建一个可以在以后兑换的Promise
。奇怪的是,Play / Java库(F.java)似乎没有公开这个API,所以你必须进入Scala Promise class。
为自己创建一个小型Scala帮助程序类PromiseUtility.scala
:
import scala.concurrent.Promise
object PromiseUtility {
def newPromise[T]() = Promise[T]()
}
然后你可以在控制器中做这样的事情(注意,我不完全理解你的用例,所以这只是如何使用这些Promises
的大致轮廓):
if (needToWaitForUserB()) {
// Create an unredeemed Scala Promise
scala.concurrent.Promise<Json> unredeemed = PromiseUtility.newPromise();
// Store it somewhere so you can access it later, e.g. a ConcurrentMap keyed by userId
storeUnredeemed(userId, unredeemed);
// Wrap as an F.Promise and, when redeemed later on, convert to a Result
return F.Promise.wrap(unredeemed.future()).map(new Function<Json, Result>() {
@Override
public Result apply(Json json) {
return ok(json);
}
});
}
// [..]
// In some other part of the code where user B connects
scala.concurrent.Promise<Json> unredeemed = getUnredeemed(userId);
unredeemed.success(jsonDataForUserB);