Java如何持续读取HTTP流式API?——LiChess Stream API集成问题求助
解决LiChess Stream API的流式响应读取问题
你说得没错,RestTemplate确实不适合处理这种无限期保持连接、持续发送数据的流式API——它的设计目标是等待完整的HTTP响应返回后再处理,所以会一直挂起直到连接被关闭,而LiChess的这个API不会主动终止连接。
下面给你两种可行的解决方案,分别用Java原生HTTP类和Spring的反应式客户端来实现:
方法一:使用Java原生HttpURLConnection
这是最底层的方式,能直接控制输入流的读取,适合不想引入额外依赖的场景:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class LichessStreamClient { public static void main(String[] args) throws Exception { String gameId = "B4ClFYzJ"; String token = "<你的TOKEN>"; URL url = new URL("https://lichess.org/api/bot/game/stream/" + gameId); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Authorization", "Bearer " + token); // 禁用自动重定向(按需调整) connection.setInstanceFollowRedirects(false); // 设置连接超时,读取超时设为0表示不主动终止,适配流式传输 connection.setConnectTimeout(5000); connection.setReadTimeout(0); // 持续读取输入流中的每行JSON数据 try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { System.out.println("收到游戏更新:" + line); // 这里可以添加你的业务逻辑,比如解析JSON、更新游戏状态 } } finally { connection.disconnect(); } } }
LiChess的流式API会以单行JSON的形式发送每次更新,所以用readLine()就能逐个捕获这些更新。
方法二:使用Spring WebClient(推荐,贴合Spring生态)
如果你想在Spring环境下优雅处理流式响应,WebClient是Spring 5+推出的反应式客户端,天生支持非阻塞的流式数据处理:
首先确保项目引入Spring WebFlux依赖(Maven示例):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
然后编写客户端代码:
import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Flux; public class LichessWebClientExample { public static void main(String[] args) { String gameId = "B4ClFYzJ"; String token = "<你的TOKEN>"; WebClient webClient = WebClient.builder() .baseUrl("https://lichess.org/api") .defaultHeader("Authorization", "Bearer " + token) .build(); // 将响应体转为字符串流,持续接收游戏更新 Flux<String> gameUpdates = webClient.get() .uri("/bot/game/stream/{gameId}", gameId) .retrieve() .bodyToFlux(String.class); // 订阅流,处理每个更新、错误和流结束事件 gameUpdates.subscribe( update -> System.out.println("收到游戏更新:" + update), error -> System.err.println("读取流时出错:" + error.getMessage()), () -> System.out.println("游戏流已关闭(游戏可能已结束)") ); // 因为是异步非阻塞模式,需要保持主线程运行,否则程序会直接退出 try { Thread.currentThread().join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
bodyToFlux会把持续发送的响应数据转为反应式流Flux,通过subscribe可以灵活处理每个数据项、异常和流终止的情况,这种方式更适合现代Spring应用的非阻塞架构。
额外注意事项
- 两种方案都要考虑连接中断的情况(比如网络异常、游戏结束后LiChess主动关闭连接),可以添加重试逻辑保证稳定性。
- 确保你的TOKEN拥有访问目标游戏流的权限(比如bot账号的相关权限)。
内容的提问来源于stack exchange,提问作者oneCoderToRuleThemAll
相关产品推荐
相关产品推荐

