8

我正在使用 OkHttp实现一个服务器发送事件库。服务器发送事件的工作原理是保持与服务器的开放 HTTP 连接,在该服务器上,“事件”可以流式传输回客户端。连接只会在错误或客户端显式断开连接时关闭。

使用 OkHttp 实现这种流式传输行为的最佳方法是什么?我试图做类似的事情:

response.body().source().readAll(new Sink() {
  @Override
  public void write(Buffer source, long byteCount) throws IOException {
    Log.d(TAG, "write(): byteCount = "+byteCount);
  }

  @Override
  public void flush() throws IOException {
    Log.d(TAG, "flush()");
  }

  @Override
  public Timeout timeout() {
    return Timeout.NONE;
  }

  @Override
  public void close() throws IOException {
    Log.d(TAG, "close()");
  }
});

使用这种方法,我最终会在 中看到日志消息write(),但有时可能需要很长时间(几分钟)。这让我认为引擎盖下可能会发生一些缓冲,并且在刷新缓冲区之前我不会得到我的数据。

我曾经用来curl验证服务器的行为是否正确。数据正在按时发送,我只是在它到达时没有收到我的回调。

我对OkHttpandOkio的经验非常有限,所以很可能我把事情搞砸了,或者忘记了设置一些选项。任何帮助是极大的赞赏!:)

4

1 回答 1

12

当你调用readAll()Okio 时,它更喜欢净吞吐量而不是延迟,因此你的消息被缓冲成块。相反,编写一个循环重复读入一个Buffer. 这会在消息到达时收到您的消息。

Buffer buffer = new Buffer();
while (!source.exhausted()) {
  long count = response.body().source().read(buffer, 8192);
  // handle data in buffer.
}
于 2015-10-31T03:37:29.830 回答