You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:58:13