dify+vue+java接入大模型流式输出

接口风格应该都是openAI

一、后端

        后端使用常规的spring boot,需要检查安装包,需要使用到webFlux+SseEmitter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

        controller层

@PostMapping(path = "/test", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter queryPage(@RequestBody TestParam param){
    return testService.test(param);
}

        service层

import cn.hutool.json.JSONObject;
import cn.kunming.kgoa.service.aihelper.api.model.param.TestParam;
import cn.kunming.kgoa.service.common.api.utils.SecurityUtil;
import io.netty.channel.ChannelOption;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;
import reactor.netty.http.client.HttpClient;




public SseEmitter test(TestParam param){
    SseEmitter emitter = new SseEmitter(300_000L);

    HttpClient httpClient = HttpClient.create().tcpConfiguration(tcpClient -> tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000));
    WebClient client = WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient))
            .baseUrl("http://192.168.70.226/v1")
            .build();
    ParameterizedTypeReference<ServerSentEvent<String>> type = new ParameterizedTypeReference<ServerSentEvent<String>>() {
    };
    JSONObject body = new JSONObject();
    body.set("inputs", new JSONObject());
    body.set("query", param.getContent());
    body.set("user", SecurityUtil.getUserId().toString());
    body.set("response_mode", "streaming");
    body.set("conversation_id", param.getConversationId());

    log.info("Dify chat body: {}", body);
    Flux<ServerSentEvent<String>> eventStream = client.post()
            .uri("/chat-messages")
            .header("Authorization", "Bearer " + "app-dgEzITfxrVqxrgSyRnS7p3I1")
            .header("Content-Type", "application/json")
            .bodyValue(body.toString())
            .retrieve()
            .bodyToFlux(type);

    eventStream.subscribe((content) -> {
        String data = content.data();
        log.info("收到数据:"+data);
    }, emitter::completeWithError, emitter::complete);
    return emitter;
}

二、前端

        前端需要使用fetch-event-source框架,因为需要使用post进行参数传递,默认的SSE是不支持post方法的。

npm install @microsoft/fetch-event-source

        实现代码

import { fetchEventSource } from "@microsoft/fetch-event-source";

const ctrl = new AbortController();
let content = ref("你好");
let send = function (content) {
  var url =
    "http://localhost:8001/kgoa-service-aihelper/aihelper/test/test";
  fetchEventSource(url, {
    method: "POST",
    headers: {
      Accept: "*/*",
      Connection: "keep-alive",
      "Content-Type": "application/json",
      Authorization: "pc_3aaac4d1343a3526cc86dd1d0f4eda35",
    },
    body: JSON.stringify({
      content: content,
    }),
    signal: ctrl.signal,
    async onopen(response) {
      console.log("Connection to server opened.");
    },
    onmessage(msg) {
      let data = JSON.parse(msg.data);
      console.log(data);
    },
    onclose() {
      // if the server closes the connection unexpectedly, retry:
      
    },
    onerror(event) {
      console.log(event);
      if (event.target.readyState === EventSource.CLOSED) {
        console.error("EventSource connection closed by the server.");
      } else if (event.target.readyState === 0) {
        console.log("对方回答结束...关闭...");
      }
    },
  });
};

### 使用 Spring Boot WebFlux 和 Dify 实现流式响应输出 Spring Boot WebFlux 是一种基于反应式编程模型的框架,能够高效地处理异步和非阻塞操作。Dify 则是一个用于构建对话式人工智能应用的服务平台。通过结合两者可以实现高效的实时数据传输。 #### 流式响应的核心概念 在现代 Web 应用中,SSE(Server-Sent Events)是一种常见的技术,允许服务器向客户端发送实时更新的数据流。WebFlux 提供了内置的支持来创建这种类型的响应[^1]。 以下是使用 Spring Boot WebFlux 和 Dify 构建流式响应的一个完整示例: --- ### 项目依赖配置 首先,在 `pom.xml` 文件中引入必要的依赖项: ```xml <dependencies> <!-- Spring Boot WebFlux --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- Optional: JSON Processing --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <!-- Dify SDK (假设存在官方库) --> <dependency> <groupId>io.dify</groupId> <artifactId>dify-sdk</artifactId> <version>1.0.0</version> <!-- 替换为实际版本号 --> </dependency> </dependencies> ``` --- ### 控制器代码示例 下面展示了一个控制器类,它利用 WebFlux 的 `Flux` 来生成流式响应,并调用了 Dify API 获取动态内容。 ```java import org.reactivestreams.Publisher; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; @RestController public class StreamController { @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> streamResponse(@RequestParam String query) { // 调用 Dify API 并返回结果作为事件流 return Flux.generate(() -> new ResponseGenerator(query), (generator, sink) -> generator.getNext(sink)); } private static class ResponseGenerator implements AutoCloseable { private final String query; private int counter = 0; public ResponseGenerator(String query) { this.query = query; } public void getNext(org.reactivestreams.Subscriber<? super String> subscriber) { try { Thread.sleep(1000); // 模拟延迟 if (counter++ < 5) { // 假设最多推送 5 次消息 String message = "Processing part " + counter + ": Query=" + query; subscriber.onNext(message); } else { subscriber.onComplete(); } } catch (Exception e) { subscriber.onError(e); } } @Override public void close() throws Exception {} } } ``` 上述代码实现了以下功能: - 定义了一条 `/stream` 接口路径,支持 SSE 协议。 - 返回的是一个无限序列对象 `Flux<String>`,每次调用都会触发新的事件。 - 结合线程休眠模拟真实场景中的延时效果。 --- ### 配置文件设置 为了启用 WebFlux 功能并调整相关参数,可以在 `application.yml` 中加入如下配置: ```yaml server: port: 8080 spring: webflux: codecs: max-in-memory-size: 2MB # 设置最大内存大小限制 ``` 此部分确保服务运行稳定的同时优化性能表现。 --- ### 测试接口 启动应用程序后,可以通过浏览器或者 Postman 工具访问 URL 地址测试该功能是否正常工作。例如输入地址 http://localhost:8080/stream?query=test ,应该可以看到连续几秒内不断刷新的内容显示出来直到完成全部五次迭代过程结束为止。 --- ### 总结说明 以上就是关于如何借助于 Spring Boot WebFlux 技术栈配合第三方工具像 Dify 进行开发从而达成理想的流媒体交互模式的具体方法介绍 。这种方法特别适合应用于聊天机器人、在线教育直播课堂等领域当中去提升用户体验质量水平。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值