1
這裏是場景。Play框架 - java.nio.channels.ClosedChannelException
我正在使用Play框架。在給定的處理函數中,play框架調用我的API webservice並將API響應返回給客戶端。客戶端通過Ajax調用來調用處理程序。有時候響應很好,但我經常在客戶端看到錯誤響應。檢查播放框架的日誌,我看到一個java.nio.channels.ClosedChannelException。
我正在使用Play 2.1.1。 我的API Webservice正在localhost:8888上運行。 Play框架在9000上運行。 API服務響應正確。 Play框架也正確執行回調,因爲我可以看到日誌。 ok()調用已從Play開始後發生錯誤。
以下是失敗的請求錯誤日誌 -
[debug] application - find...
[debug] application - id = 647110558
[trace] c.jolbox.bonecp - Check out connection [9 leased]
[trace] c.jolbox.bonecp - Check in connection [9 leased]
[debug] application - socialUser = SocialUser(UserId(647110558,facebook),Arvind,Batra,Arvind Batra,Some([email protected]),null,AuthenticationMethod(oauth2),null,Some(OAuth2Info(CAAHNVOUuNZAEBAMa3CPLUEsZA2Tp5xWGXylO9HggBY0TCfwsIn4iGUdlRMpuNPLxYcObKO5ZBZCU0ghS9ymHZC3s9YXpsfPix9AM1EhNyETvDR85HHYg8j7JO0h2WzGZBsKJdbFPhPmkD6ZBZAq6KTT8RLSQrmpfnHQZD,null,null,null)),null)
[info] application - Calling interest for fff
[info] application - user is not null
[trace] c.jolbox.bonecp - Check out connection [9 leased]
[info] application - interest=fff, userInfo:[email protected]
[info] application - http://localhost:8888/api/add_interest/1/fff
[debug] c.n.h.c.p.n.NettyAsyncHttpProvider - Using cached Channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
for uri http://localhost:8888/api/add_interest/1/fff
[debug] c.n.h.c.p.n.NettyAsyncHttpProvider -
Using cached Channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
for request
DefaultHttpRequest(chunked: false)
GET /api/add_interest/1/fff HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: */* User-Agent: NING/1.0
[debug] c.n.h.c.p.n.NettyAsyncHttpProvider -
Request DefaultHttpRequest(chunked: false)
GET /api/add_interest/1/fff HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: */*
User-Agent: NING/1.0
Response DefaultHttpResponse(chunked: true)
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Thu, 04 Jul 2013 12:14:40 GMT
Transfer-Encoding: chunked
[debug] c.n.h.c.p.n.NettyConnectionsPool - Adding uri: http://localhost:8888 for channel [id: 0x9d1dee2d, /127.0.0.1:50316 => localhost/127.0.0.1:8888]
[info] application - {"status":"success"}
[info] application - {"status":"ok","exists":false}
[trace] play - Sending simple result: SimpleResult(200, Map(Content-Type -> application/json; charset=utf-8, Set-Cookie ->))
[debug] play - java.nio.channels.ClosedChannelException
[trace] application - Exception caught in Netty
java.nio.channels.ClosedChannelException: null
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:409) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:127) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:99) ~[netty.jar:na]
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:36) ~[netty.jar:na]
at org.jboss.netty.channel.Channels.write(Channels.java:725) ~[netty.jar:na]
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.doEncode(OneToOneEncoder.java:71) ~[netty.jar:na]
[debug] c.n.h.c.p.n.NettyConnectionsPool - Entry count for : http://localhost:8888 : 2
這裏是我的示例代碼 -
public static Result addInterestCallback(WS.Response response) {
if (response == null) {
return badRequest();
}
ObjectNode result = (ObjectNode) response.asJson();
try {
Logger.info(result.toString());
if (result.has("status")) {
String status = result.get("status").getTextValue();
if(status.equals("error")) {
result.put("error", "Oops, cannot process your request. Sorry.");
Logger.info("error");
return badRequest(result);
}
else if(status.equals("exists")) {
result.put("exists",true);
}
else {
result.put("exists",false);
}
result.put("status", "ok");
} else {
//do something
Logger.info("result has no status");
}
Logger.info(result.toString());
} catch (Exception e) {
e.printStackTrace();
}
return ok(result);
}
@BodyParser.Of(BodyParser.Json.class)
@SecureSocial.UserAwareAction
public static Result addInterest() {
JsonNode json = request().body().asJson();
String interestName = json.findPath("interestName").getTextValue();
Logger.info("Calling interest for " + interestName);
Identity user = (Identity) ctx().args.get(SecureSocial.USER_KEY);
if (user == null) {
ObjectNode result = Json.newObject();
result.put("error", "requires-login");
Http.Context ctx = Http.Context.current();
ctx.flash().put("error", play.i18n.Messages.get("securesocial.loginRequired"));
result.put("redirect", RoutesHelper.login().absoluteURL(ctx.request(), IdentityProvider.sslEnabled()));
return ok(result);
}
Logger.info("user is not null");
if(interestName == null) {
ObjectNode result = Json.newObject();
result.put("error", "Empty input");
return badRequest(result);
}
//get user
EBUser ebUser = Application.getEBUser();
Logger.info("interest="+interestName+", userInfo:" + ebUser.toString());
//Call addInterst API.
String apiEndpoint = Play.application().configuration().getString(AppConstants.EB_API_ENDPOINT);
String url = "";
try {
url = apiEndpoint + "add_interest/" + ebUser.getId() + "/" + URLEncoder.encode(interestName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
ObjectNode result = Json.newObject();
result.put("error", "Cant parse interest properly");
Logger.info("error " + result.toString());
return badRequest(result);
}
Logger.info(url);
Promise<WS.Response> promiseOfAPI = WS.url(url).get();
Promise<Result> promiseOfResult = promiseOfAPI.map(
new Function<WS.Response, Result>() {
@Override
public Result apply(WS.Response response) throws Throwable {
return addInterestCallback(response);
}
});
return async(promiseOfResult);
}
處理器的名稱是addInterest。
任何可能在這裏發生的指針?
對,例如,瀏覽器現在關閉,服務器仍然向消失的客戶端發送消息。 – Twistleton
@Twistleton錯誤。這會導致「連接重置」。這是由應用程序關閉自己的頻道引起的。 – EJP