android - OkHttp 半闭流用于 Android 上 AVS 的下行 channel

标签 android okhttp alexa-voice-service

我在 Android 上使用 OkHttp v3.6.0 与 AVS v20160207 进行通信。我成功地在事件 channel 上与 AVS 通信,以发送 SpeechRecognizer 事件和接收匹配的 SpeechSynthesizer 指令。

当建立与下行 channel 的连接时,我收到 HTTP 200 Success 的成功响应,然后阻塞流以接收入站数据。当我要求 Alexa 设置“5 秒计时器”时,我收到她的提示说她将启动计时器,但我从未在下行 channel 收到任何指示来告诉我设置计时器。

同样有趣的是,如上所述,我从下行 channel 收到 HTTP 200 成功,然后可以阻止 response.body().source()。累()。但是在被阻止 10 分钟并且没有收到任何东西后,流被关闭并且我收到以下异常:

Response with Error okhttp3.internal.http2.StreamResetException: stream was reset: CANCEL at okhttp3.internal.http2.Http2Stream$FramingSource.checkNotClosed(Http2Stream.java:436) at okhttp3.internal.http2.Http2Stream$FramingSource.read(Http2Stream.java:338) at okio.ForwardingSource.read(ForwardingSource.java:35) at okio.RealBufferedSource$1.read(RealBufferedSource.java:409) at java.io.InputStream.read(InputStream.java:101) at com.example.demo.alexaassistant.AlexaVoiceServices.interfaces.DownChannelRunnable.run(DownChannelRunnable.java:192) at java.lang.Thread.run(Thread.java:761)

请注意,我已经尝试了此线程中的所有建议: Establishing a downchannel with Okhttp?

private static final long CONNECTION_POOL_TIMEOUT_MILLISECONDS = 60 * 60 * 1000;

        ConnectionPool connectionPool = new ConnectionPool(5,
            CONNECTION_POOL_TIMEOUT_MILLISECONDS, TimeUnit.MILLISECONDS);

        /**
         * Create a customized HTTP/2 interface.
         *
         * For the AVS's downchannel, we need to
         * disable the timeout on the read.
         */
        OkHttpClient downChannelClient = httpClient.newBuilder()
            .connectTimeout(0, TimeUnit.MILLISECONDS)  // 0 => no timeout.
            .readTimeout(0, TimeUnit.MILLISECONDS)
            .connectionPool(connectionPool)
            .build();

        final Request request = new Request.Builder()
            .url(url)
            .get()
            .addHeader("Authorization", "Bearer " + this.accessToken)
            .build();
        Log.d(TAG, "downchannel URL ==> " + request.url().toString());
        Log.d(TAG, "downchannel headers ==> " + request.headers().toString());

        Response response = null;
        try
        {
            currentCall = downChannelClient.newCall(request);
    response = currentCall.execute();
    BufferedSource bufferedSource = response.body().source();

    Log.i(TAG, "Downchannel ==> HTTP response code: " + response.code());

    Buffer buffer = new Buffer();

    while (!bufferedSource.exhausted())
    {
        Log.w(TAG, "downchannel received data!!!");
        bufferedSource.read(buffer, 8192);
        Log.d(TAG, "Size of data read: " + buffer.size());
    }

    Log.d(TAG, "Response: " + buffer.toString());
}
catch (IOException e)
{
    Log.d(TAG, "Response with Error", e);
}
finally
{
    if (response != null)
    {
        response.close();
    }
}

编辑:

Amazon 的文档说,客户端需要与服务器建立一个连接,因此 POST 和 GET 流将发送到该连接以及处于半关闭流状态的下行 channel 。 OkHttp2 支持吗?

最佳答案

最后,我现在从下行 channel 中的服务器接收数据。当我在创建下行 channel 时收到 200 响应后,我所做的是 SynchronizeState。医生说:

  1. To establish a downchannel stream your client must make a GET request to /{{API version}}/directives within 10 seconds of opening the connection with AVS. The request should look like this:

  2. After establishing the downchannel stream, your client must synchronize it’s components’ states with AVS. This requires making a POST request to /{{API version}}/events on a new event stream on the existing connection (Note: Do not open a new connection). This event stream should be closed when your client receives a response (directive). The following is an example SynchronizeState event:

希望对您有所帮助。我现在正在努力尝试解析下行 channel 中的结果。您的代码应该:

Log.i(TAG, "Downchannel ==> HTTP response code: " + response.code());

...

synchronizeState();

....

Buffer buffer = new Buffer();

while (!bufferedSource.exhausted())
{
    Log.w(TAG, "downchannel received data!!!");
    bufferedSource.read(buffer, 8192);
    Log.d(TAG, "Size of data read: " + buffer.size());
}

关于android - OkHttp 半闭流用于 Android 上 AVS 的下行 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42214222/

相关文章:

android - Chrome DevTools 损坏 - Stetho 无法使用

javascript - Alexa 技能套件 : How to add an image to a standard card using JS

android - ActiveAndroid:锁定更新记录?

java - 如何使用 Fragments 为 Android 创建二维码生成器

java - OkHttp3 抓取的 HTML 页面不完整,需要 JavaScript 吗?

amazon-web-services - 以编程方式配置架构和话语

ios - 如何让 Alexa 在我的 iOS 应用程序上运行?

android - 回收站 View 未填充宽度

java - Android如何从外部存储获取资源标识符

android - 使用嵌套的 json 对象改造获取请求