我正在尝试建立与 API 端点的持久 HTTP 连接,该端点在新事件发生时发布分块的 JSON 响应。我想提供一个回调,每次服务器发送一个新的数据块时都会调用它,并无限期地保持连接打开。据我所知,既不HttpClient
也不HttpUrlConnection
提供此功能。
有没有办法在不使用 TCP 套接字的情况下实现这一点?
一种解决方案是使用分隔符\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");
}
}
据我所知,AndroidHttpURLConnection
不支持通过持久的 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
}