admin管理员组

文章数量:1122846

I try to use the spring webflux client to call a rest API that returns Server-Sent-Event (chatgpt).

Here is my client :

public interface OpenAIAsyncClient {

  @PostExchange(url = "/chat/completions", accept = MediaType.TEXT_EVENT_STREAM_VALUE)
  Flux<ChatCompletionResult> request(@RequestBody AbstractChatCompletionRequest request);
}

So I will receive a list of json object like this :

{"id":"chatcmpl-id","object":"chatpletion.chunk","created":1732310107,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]}
...
{"id":"chatcmpl-id","object":"chatpletion.chunk","created":1732310107,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
[DONE]

But the last line is a [DONE] string that breaks jackson deserialization. Is there a way to handle this correctly with the spring webflux client ?

I try to use the spring webflux client to call a rest API that returns Server-Sent-Event (chatgpt).

Here is my client :

public interface OpenAIAsyncClient {

  @PostExchange(url = "/chat/completions", accept = MediaType.TEXT_EVENT_STREAM_VALUE)
  Flux<ChatCompletionResult> request(@RequestBody AbstractChatCompletionRequest request);
}

So I will receive a list of json object like this :

{"id":"chatcmpl-id","object":"chat.completion.chunk","created":1732310107,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]}
...
{"id":"chatcmpl-id","object":"chat.completion.chunk","created":1732310107,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
[DONE]

But the last line is a [DONE] string that breaks jackson deserialization. Is there a way to handle this correctly with the spring webflux client ?

Share Improve this question asked Nov 22, 2024 at 21:19 Oreste VironOreste Viron 3,7954 gold badges26 silver badges39 bronze badges 2
  • Is the string ``` [DONE] ``` not return by yourself? i mean the server side is all in your control ,so you can filter it in SSE . – Peng Commented Nov 25, 2024 at 5:21
  • @Peng : the server side is Chatgpt, the client side is spring app. – Oreste Viron Commented Nov 25, 2024 at 8:20
Add a comment  | 

1 Answer 1

Reset to default 0

Ok, the way I did It is to override a Jackson2JsonDecoder :

public class IgnoreDoneJackson2JsonDecoder extends Jackson2JsonDecoder {

  public IgnoreDoneJackson2JsonDecoder() {
    super();
  }

  public IgnoreDoneJackson2JsonDecoder(ObjectMapper mapper, MimeType... mimeTypes) {
    super(mapper, mimeTypes);
  }

  @Override
  public Object decode(DataBuffer buffer, @NotNull ResolvableType targetType, MimeType mimeType,
      Map<String, Object> hints) throws DecodingException {
    if (buffer.capacity() > 5) {
      var begin = buffer.toString(0, 6, Charset.defaultCharset());
      if ("[DONE]".equals(begin)) {
        return null;
      }
    }
    return super.decode(buffer, targetType, mimeType, hints);
  }
}

And set it when creating the weclient :

var webClient = WebClient.builder()
    .baseUrl(url)
    .codecs(configurer -> configurer.defaultCodecs().serverSentEventDecoder(customDecoder))
    .build();

本文标签: Correctly handle DONE for Server Sent Event with spring webflux clientStack Overflow