chatGpt如何融入自己的项目

447 阅读2分钟

chatGpt如何融入自己的项目

最近chatGpt也是相当的火,各位小伙伴应该都挺喜欢这个能取代自己的家伙的。

我这里利用webSocket + chatGpt实现了简单的聊天室。代码真的非常简单!

后端

核心依赖

<!--        websocket-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
<!--        openai-->
        <dependency>
            <groupId>com.unfbx</groupId>
            <artifactId>chatgpt-java</artifactId>
            <version>1.0.8</version>
        </dependency>

webSocket相关

@Slf4j
@ServerEndpoint("/chat/{userId}")
@Component
public class ChatServer {
    /**
     *  与某个客户端的连接对话,需要通过它来给客户端发送消息
     */
    private Session session;
    /**
     * 标识当前连接客户端的用户名
     */
    private Long userId;
​
​
    /**
     *  用于存所有的连接服务的客户端,这个对象存储是安全的
     */
    private static ConcurrentHashMap<Long, ChatServer> webSocketSet = new ConcurrentHashMap<>();
​
​
    public static ChatServer chatServer;
​
    @Autowired
    AiService aiService;
​
​
​
    @PostConstruct
    private void initChatServer(){
        chatServer = this;
        chatServer.aiService = this.aiService;
    }
​
    @OnOpen
    public void OnOpen(Session session, @PathParam(value = "userId") Long userId){
​
        this.session = session;
        this.userId = userId;
        // name是用来表示唯一客户端,如果需要指定发送,需要指定发送通过name来区分
        webSocketSet.put(userId,this);
​
        log.info("[WebSocket] 连接成功,当前连接人数为:={}",webSocketSet.size());
    }
​
​
​
​
    @OnClose
    public void onClose(){
        webSocketSet.remove(this.userId);
        log.info("[WebSocket] 退出成功,当前连接人数为:={}",webSocketSet.size());
    }
​
​
​
    @OnMessage
    public void OnMessage(String message){
        log.info("[WebSocket] 收到消息:{}",message);
​
        String response = chatServer.aiService.getResponseFromOpenAi(message);
        appointSending(userId,response);
    }
    @OnError
    public void onError(Session session, Throwable t) {
        //什么都不想打印都去掉就好了
        log.info("【websocket消息】出现未知错误 ");
        //打印错误信息,如果你不想打印错误信息,去掉就好了
        //这里打印的也是  java.io.EOFException: null
        t.printStackTrace();
    }
​
​
​
    /**
     * 群发
     * @param message
     */
    public void groupSending(String message){
        for (Long userId : webSocketSet.keySet()){
            try {
                webSocketSet.get(userId).session.getBasicRemote().sendText(message);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
​
​
​
    /**
     * 指定发送
     * @param userId
     * @param message
     */
    public void appointSending(Long userId,String message){
        try {
            webSocketSet.get(userId).session.getBasicRemote().sendText(message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
​

ChatGpt相关

申请key

复制,保存好!

业务

@Service
public class AiServiceImpl implements AiService {
​
    @Value("${openai.key}")
    private String openaiKey;
​
​
    @Value("${openai.host}")
    private String apiHost;
​
​
    private static String PRESET ="下面的对话你都需要以一个小可爱的身份进行对话,语气欢快;";
​
    @Override
    public String getResponseFromOpenAi(String content) {
        OpenAiClient openAiClient = OpenAiClient.builder()
                .apiKey(Arrays.asList(openaiKey))
                .apiHost(apiHost)
                .build();
        //聊天模型:gpt-3.5
        ChatCompletionResponse chatCompletionResponse = getMessage(content,openAiClient);
        StringBuilder response = new StringBuilder();
        chatCompletionResponse.getChoices().forEach(e -> {
            response.append(e.getMessage().getContent()).append("\n");
        });
        return response.toString();
    }
​
    public ChatCompletionResponse getMessage(String content, OpenAiClient openAiClient) {
        Message preMessage = Message.builder().role(Message.Role.USER).content(PRESET).build();
        Message userMessage = Message.builder().role(Message.Role.USER).content(content).build();
​
        ChatCompletion chatCompletion = ChatCompletion.builder().messages(Arrays.asList(preMessage,userMessage)).build();
        ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
        return chatCompletionResponse;
    }
}

application.yml

openai:
  host: https://******  //代理网址
  key: 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 //secretKey

代理网址

登录这个网址www.ichati.cn/deploy/proj…,把key传进去,把返回的网址填入上面的

openai:
  host: https://******  //代理网址

前端

<template>
  <div style="">
    <div class="basic" style="overflow: hidden;">
      <div style="padding: 10px;font-size: 14px;display: flex;flex-direction: row;" v-for="msg in msgList" class="animate__animated animate__fadeInLeft ">
        <a-avatar :src="avatar" v-show="msg.auth === 'user'"></a-avatar>
        <div :style="msg.style">
          {{ msg.text }}
        </div>
      </div>
    </div>
    <div style="position:absolute;bottom:0px;width: 100%;padding: 10px;display: flex;flex-direction: column">
      <a-button type="dashed" style="width: 150px;margin: 0 auto 20px auto " @click="sendMessageAgain">regenerate
        answer
      </a-button>
      <a-input v-model:value="inputText" @keyup.enter="sendMessage" type="primary" placeholder="Send a message ..."/>
    </div>
  </div>
</template>
​
<script setup lang="ts">
import SocketService from '../utils/WebSocketUtils';
import {onMounted, reactive, ref} from "vue";
import {message} from "ant-design-vue";
import {useUserStore} from "../store/userStore";
import '../../node_modules/animate.css/animate.css'
const userStore = useUserStore();
const inputText = ref('')
const againText = ref('')
const msgList: any = ref([])
const avatar = ref()
​
onMounted(()=>{
  if (!userStore.getUserAvatar() || userStore.getUserAvatar() === '') {
    avatar.value = "https://***.com"
    return;
  }
  avatar.value = userStore.getUserAvatar()
})
​
​
​
const data = reactive({
  socketServe: SocketService.Instance,
});
//@ts-ignore
SocketService.Instance.connect(userStore.getUserId());
data.socketServe = SocketService.Instance;
const sendMessage = () => {
​
  if (inputText.value.length >= 200) {
    message.error("不得超过200字")
    return;
  }
​
  //@ts-ignore
  data.socketServe.send(inputText.value);
​
  let showText: any = {}
  showText.text = inputText.value
  showText.auth = 'user'
  showText.style = {
    padding: '10px',
    fontSize: '14px',
    color: 'black'
  }
  msgList.value.push(showText);
  console.log('发送数据', showText.text)
  againText.value = inputText.value
  inputText.value = ''
};
//@ts-ignore
data.socketServe.ws.onmessage = async (msg: any) => {
  console.log(msg, '从服务端获取到了数据');
  let showText: any = {}
  showText.text = msg.data
  showText.auth = 'robot'
  showText.style = {
    padding: '10px',
    fontSize: '8px',
    color: 'black',
    borderTop: '1px solid #e5e5e5',
    borderBottom: '1px solid #e5e5e5',
    backgroundColor: '#f7f7f8'
  }
  await msgList.value.push(showText)
};
​
const sendMessageAgain = () => {
  //@ts-ignore
  data.socketServe.send(againText.value);
}
​
​
</script>
​
<style scoped>
.basic {
  display: flex;
  flex-direction: column;
  max-height: 550px;
  overflow: scroll;
}
</style>
export default class SocketService {
    static instance = null;
    static get Instance() {
        if (!this.instance) {
            // @ts-ignore
            this.instance = new SocketService();
        }
        return this.instance;
    }
    // 和服务端连接的socket对象
    ws = null;
    // 标识是否连接成功
    connected = false;
    // 记录重试的次数
    sendRetryCount = 0;
    // 重新连接尝试的次数
    connectRetryCount = 0;
​
    baseURL_TEMP = import.meta.env.DEV ? import.meta.env.VITE_BASE_WEBSOCKET_URL_DEV : import.meta.env.VITE_BASE_WEBSOCKET_URL_PROD;
    //  定义连接服务器的方法
    connect(userId:number) {
        // 连接服务器
        if (!window.WebSocket) {
            return console.log('您的浏览器不支持WebSocket');
        }
        let url = this.baseURL_TEMP + userId;
        // @ts-ignore
        this.ws = new WebSocket(url);
        // 连接成功的事件
        // @ts-ignore
        this.ws.onopen = () => {
            console.log('连接服务端成功了');
            this.connected = true;
            // 重置重新连接的次数
            this.connectRetryCount = 0;
        };
        // 1.连接服务端失败
        // 2.当连接成功之后, 服务器关闭的情况
        // @ts-ignore
        this.ws.onclose = () => {
            console.log('连接服务端失败');
            this.connected = false;
            this.connectRetryCount++;
            setTimeout(() => {
                this.connect(userId);
            }, 500 * this.connectRetryCount);
        };
        // 得到服务端发送过来的数据
        // @ts-ignore
        this.ws.onmessage = msg => {
            console.log(msg.data, '从服务端获取到了数据');
        };
    }
​
    // 发送数据的方法
    send(data:string) {
        // 判断此时此刻有没有连接成功
        if (this.connected) {
            this.sendRetryCount = 0;
            try {
                // @ts-ignore
                this.ws.send(JSON.stringify(data));
            } catch (e) {
                // @ts-ignore
                this.ws.send(data);
            }
        } else {
            this.sendRetryCount++;
            setTimeout(() => {
                this.send(data);
            }, this.sendRetryCount * 500);
        }
    }
}
​

Over!!!!