问题描述
下面的代码有很多调试打印语句。我在谷歌浏览和浏览其他堆栈溢出帖子时发现,人们通常在发出同步事件请求后返回一个json文件,但是在调用Log.d("syncResponse_body","Result: " + response.body().string());
时约30秒我什么都没得到,然后SocketTimeoutException。这是我关注的亚马逊文档:
https://developer.amazon.com/en-US/docs/alexa/alexa-voice-service/manage-http2-connection.html
private Response makeSyncRequest(OkHttpClient downChannelClient,String accesstoken) throws IOException {
final Request getRequest = new Request.Builder()
.url("https://alexa.na.gateway.devices.a2z.com/" + AVS_API_VERSION + "/directives")//endpoint url
.get()
.addHeader("authorization","Bearer " + accesstoken)
.build();
Log.d("Request_header",getRequest.toString());
Call currentCall = downChannelClient.newCall(getRequest);
Response syncResponse = currentCall.execute();
Log.d("Response_success",String.valueOf(syncResponse.isSuccessful()));
Log.d("Response_str",syncResponse.toString());
return syncResponse;
}
private Response syncronizeWithAVS(OkHttpClient downChannelClient,String accesstoken) throws IOException {
Response syncResponse = makeSyncRequest(downChannelClient,accesstoken);
String msgid = UUID.randomUUID().toString();
String speakToken = "";
long offsetMili = 20; // if lags put down to 10.
String playerActivity = "PLAYING";
// ------------------------------
final String JSON_SYNC = "{\"context\":[{\"header\":{\"namespace\":\"SpeechRecognizer\",\"name\":\"RecognizerState\"},\"payload\":{\"wakeword\":\"ALEXA\"}},{\"header\":{\"namespace\":\"SpeechSynthesizer\",\"name\":\"SpeechState\"},\"payload\":{\"token\":\"" + speakToken + "\",\"offsetInMilliseconds\":" + offsetMili + ",\"playerActivity\":\"" + playerActivity + "\"}}],\"event\":{\"header\":{\"namespace\":\"System\",\"name\":\"SynchronizeState\",\"messageId\":\"" + msgid + "\"},\"payload\":{}}}";
List<MultipartBody.Part> partList = new ArrayList<>();
MultipartBody.Part syncPart = MultipartBody.Part.create(Headers.of("Content-disposition","form-data; name=\"Metadata\""),RequestBody.create(JSON_SYNC,JSON_TYPE));
partList.add(syncPart);
RequestBody body = new MultipartBody(ByteString.encodeUtf8(BOUNDARY_TERM),MultipartBody.FORM,partList);
Log.d("part",syncPart.headers().toString());
Log.d("body",body.contentType().toString());
final Request postRequest = new Request.Builder()
.url("https://alexa.na.gateway.devices.a2z.com/" + AVS_API_VERSION + "/events")//endpoint url
.post(body)
.addHeader("authorization","Bearer " + accesstoken)
.build();
Log.d("post_request",postRequest.toString());
Log.d("post_req_body",JSON_SYNC);
Response postResponse = null;
try {
postResponse = downChannelClient.newCall(postRequest).execute();
Log.d("Post_succes","" + postResponse.isSuccessful());
Log.d("Post_succes","" + postResponse.toString());
Log.d("Post_Response","Result: " + postResponse.body().string());
} catch (IOException e) {
e.printstacktrace();
}
return syncResponse;
}
private void login(AuthorizeResult authorizeResult) {
...
Response response = syncronizeWithAVS(downChannelClient,accesstoken);
Log.d("syncResponse_body","Result: " + response.body().string());
...
}
D/accesstoken: authorizeResult.toString(): com.amazon.identity.auth.device.api.authorization.AuthorizeResult@f028508b
accesstoken: <censored accesstoken for this forum post>
D/Request_header: Request{method=GET,url=https://alexa.na.gateway.devices.a2z.com/v20160207/directives,headers=[authorization:Bearer <censored accesstoken for this forum post>]}
D/Response_success: true
D/Response_str: Response{protocol=h2,code=200,message=,url=https://alexa.na.gateway.devices.a2z.com/v20160207/directives}
D/part: Content-disposition: form-data; name="Metadata"
D/body: multipart/form-data; boundary=------------------------qM9tn4VZyj
D/post_request: Request{method=POST,url=https://alexa.na.gateway.devices.a2z.com/v20160207/events,headers=[authorization:Bearer <censored accesstoken for this forum post>]}
D/post_req_body: {"context":[{"header":{"namespace":"SpeechRecognizer","name":"RecognizerState"},"payload":{"wakeword":"ALEXA"}},{"header":{"namespace":"SpeechSynthesizer","name":"SpeechState"},"payload":{"token":"","offsetInMilliseconds":20,"playerActivity":"PLAYING"}}],"event":{"header":{"namespace":"System","name":"SynchronizeState","messageId":"c5488d48-c758-46a0-aeea-e305a452df90"},"payload":{}}}
D/Post_succes: true
Response{protocol=h2,code=204,url=https://alexa.na.gateway.devices.a2z.com/v20160207/events}
D/Post_Response: Result:
然后,在30秒后,
W/System.err: java.net.socketTimeoutException: timeout
at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.kt:677)
at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.kt:686)
at okhttp3.internal.http2.Http2Stream$FramingSource.read(Http2Stream.kt:382)
W/System.err: at okhttp3.internal.connection.Exchange$ResponseBodySource.read(Exchange.kt:276)
at okio.Buffer.writeall(Buffer.kt:1655)
at okio.RealBufferedSource.readString(RealBufferedSource.kt:95)
at okhttp3.ResponseBody.string(ResponseBody.kt:187)
at aut.rnd.alexa.ui.account.AccountFragment.login(AccountFragment.java:362)
at aut.rnd.alexa.ui.account.AccountFragment.access$300(AccountFragment.java:65)
at aut.rnd.alexa.ui.account.AccountFragment$TokenListener.onSuccess(AccountFragment.java:381)
at aut.rnd.alexa.ui.account.AccountFragment$TokenListener.onSuccess(AccountFragment.java:373)
at com.amazon.identity.auth.device.api.authorization.AuthorizationManager$3.onSuccess(AuthorizationManager.java:276)
at com.amazon.identity.auth.device.thread.AuthzCallbackFuture$1.onSuccess(AuthzCallbackFuture.java:36)
at com.amazon.identity.auth.device.thread.MAPCallbackFuture.onSuccess(MAPCallbackFuture.java:88)
at com.amazon.identity.auth.device.authorization.InternalAuthManager$2$1.onSuccess(InternalAuthManager.java:119)
at com.amazon.identity.auth.device.authorization.TokenHelper.getToken(TokenHelper.java:65)
W/System.err: at com.amazon.identity.auth.device.authorization.InternalAuthManager$2.run(InternalAuthManager.java:115)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
解决方法
guide you mention包含以下信息:
读取超时:因为AVS需要打开下行通道流 在AVS和客户端之间的连接寿命内,设置任何读取 您的客户至少要超时60分钟。
因此,您当然应该增加此连接的读取超时。为此,请使用以下代码(位于this answer中):
downChannelClient.setReadTimeout(60,TimeUnit.MINUTES);