我正在使用Google Cloud Endpoints创建客户端 - 服务器应用程序,而我现在正在使用Android版本。当我的设备通过Wi-Fi连接到互联网时,一切正常。但是,当我通过3G连接时,有时远程调用端点API会失败并显示以下堆栈跟踪:
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:552)
at libcore.io.IoBridge.recvfrom(IoBridge.java:516)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
at java.io.InputStream.read(InputStream.java:163)
at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142)
at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
at libcore.io.Streams.readAsciiLine(Streams.java:201)
at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:560)
at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:813)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeTunnel(HttpsURLConnectionImpl.java:493)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:463)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:442)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:165)
at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:93)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:965)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at com.projectbamboo.android.activity.MenuActivity$5.doInBackground(MenuActivity.java:175)
at com.projectbamboo.android.activity.MenuActivity$5.doInBackground(MenuActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: libcore.io.ErrnoException: recvfrom failed: ECONNRESET (Connection reset by peer)
at libcore.io.Posix.recvfromBytes(Native Method)
at libcore.io.Posix.recvfrom(Posix.java:131)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
... 30 more
以下是在这种情况下失败的请求的代码,但它们都以相同的方式被调用,并且可以(并且确实)在其中任何一个中发生:
final LinearLayout list = (LinearLayout) findViewById(R.id.manageGamesLayout);
list.removeAllViews();
AsyncTask<Void, Void, CreatedGameList> listCreated = new AsyncTask<Void, Void, CreatedGameList>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
refreshing--;
}
@Override
protected CreatedGameList doInBackground(Void... arg) {
Gameapi apiServiceHandle = AppConstants.getApiServiceHandle();
GetCreatedGames function;
try {
function = apiServiceHandle.getCreatedGames();
return function.execute(); // <------ line 175 is here
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(CreatedGameList gamesList) {
refreshing++;
List<CreatedGame> list = gamesList.getObjectsList();
if(list == null)
return;
for(CreatedGame game : list){
addCreated(game);
}
}
};
listCreated.execute();
以下是AppConstants,它在那里被称为:
private static GoogleAccountCredential _credential;
public static final JsonFactory JSON_FACTORY = new AndroidJsonFactory();
public static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
public static Gameapi getApiServiceHandle() {
// Use a builder to help formulate the API request.
Gameapi.Builder helloWorld = new Gameapi.Builder(AppConstants.HTTP_TRANSPORT,
AppConstants.JSON_FACTORY,_credential).setApplicationName("Project Bamboo");
return helloWorld.build();
}
该设备是三星Galaxy S3 mini。当通过3G连接时,我可以在正常速度测试和~10mbit / s下载时获得~90ms的ping,因此可能会更糟糕。
我想知道是否有任何方法可以避免这个问题,或者只是如何验证这种情况是否会再次尝试几次或类似的事情。
感谢您的帮助。
答案 0 :(得分:0)
您可能正在执行&#34;加载请求&#34;
什么是加载请求?某些请求运行较慢,因为App Engine需要创建新的Java虚拟机(JVM)来为请求提供服务。
引自“{3}}
如果服务器需要更多时间来处理请求,因为正在启动新实例并结合3G网络中的延迟可能会触发此类错误。
如何测试?
如果出现错误,请检查最近是否创建了新实例,如果是,您可能要执行某些预热请求
您可以使用预热请求来避免某些加载请求。在发出任何实时请求之前,预热请求会在新实例上加载应用程序代码。
有关预热请求的更多信息this google page
所有引用均来自此Google文章here