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

接口风格应该都是openAI

一、后端

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

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

controller层

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

service层

java 复制代码
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方法的。

bash 复制代码
npm install @microsoft/fetch-event-source

实现代码

javascript 复制代码
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("对方回答结束...关闭...");
      }
    },
  });
};
相关推荐
君顾13 小时前
智慧零售实战指南:从技术架构到落地方案全解析
java·开发语言·零售
zhanghe6874 小时前
es的密码带有特殊字符,导出
java
梦曦i4 小时前
@meng-xi/create-uni-app vs unibest:轻量脚手架与重型框架的定位之争
前端·uni-app
平头哥技术团队4 小时前
Day 10 | 工欲善其事:VS Code 配置与项目归档
android·开发语言·前端·javascript·html·交互
pnoker4 小时前
IoT DC3 概念解读:把设备抽象成一套语义模板——位号、指令、事件与面向智能体的设备建模
java·人工智能·物联网·iot·dc3
my_realmy4 小时前
Java SE 基础学习笔记(一):面向对象、继承多态、抽象接口与异常(JDK 8)
java·多线程·并发··生产者消费者模式
乌恩大侠5 小时前
GH200 新增 NVMe SSD 分区、格式化与挂载完整流程
运维·服务器·前端
天远数科5 小时前
风险治理实战:基于天远车信盟出险构建自动化理赔核保流水线
java·网络·人工智能·自动化
yume_sibai5 小时前
Element Plus 数据展示组件完全指南(15个核心组件)
前端·javascript·vue.js
骇客野人5 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端