【问题标题】:Android - How can I open a persistent HTTP connection that receives chunked responses?Android - 如何打开接收分块响应的持久 HTTP 连接?
【发布时间】:2014-08-20 01:47:37
【问题描述】:

我正在尝试建立与 API 端点的持久 HTTP 连接,该端点在新事件发生时发布分块 JSON 响应。我想提供一个回调,每次服务器发送一个新的数据块时都会调用它,并无限期地保持连接打开。据我所知,HttpClientHttpUrlConnection 都没有提供此功能。

有没有办法在不使用 TCP 套接字的情况下做到这一点?

【问题讨论】:

标签: android http chunked


【解决方案1】:

一种解决方案是使用分隔符(例如\n\n)来分隔每个 json 事件。您可以在发送之前从原始 json 中删除空白行。调用setChunkedStreamingMode(0) 允许您在内容进入时读取内容(而不是在整个请求被缓冲之后)。然后你可以简单地遍历每一行,存储它们,直到到达一个空行,然后将存储的行解析为 JSON。

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setChunkedStreamingMode(0);
conn.connect();

InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuffer sBuffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
    if (line.length() == 0) {
        processJsonEvent(sBuffer.toString());
        sBuffer.delete(0, sBuffer.length());
    } else {
        sBuffer.append(line);
        sBuffer.append("\n");
    }
}

【讨论】:

    【解决方案2】:

    据我所知,Android 的 HttpURLConnection 不支持通过持久的 HTTP 连接接收数据块;而是等待响应完全完成。

    但是,使用 HttpClient 可以:

    HttpClient httpClient = new DefaultHttpClient();
    
    try {
        HttpUriRequest request = new HttpGet(new URI("https://www.yourStreamingUrlHere.com"));
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    
    try {
        HttpResponse response = httpClient.execute(request);
        InputStream responseStream = response.getEntity().getContent();
        BufferedReader rd = new BufferedReader(new InputStreamReader(responseStream));
    
        String line;
        do {
            line = rd.readLine();
            // handle new line of data here
        } while (!line.isEmpty());
    
    
        // reaching here means the server closed the connection
    } catch (Exception e) {
        // connection attempt failed or connection timed out
    }
    

    【讨论】:

    • 不幸的是,HttpClient 已被 HttpURLConnection 取代(在 Android 6 中已被删除)。
    • 我认为你对 HttpURLConnetction 的理解是错误的,它可以使用 SAX Handler 接收块数据
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多