springboot + websocket对接文心一言接口实现简单上下文聊天(贴代码)

如题,第一次用websocket,做了个这玩意,只做了上下文的聊天,没做流式。
中间还有个低级报错但卡了好久,具体可以看【错误记录】websocket连接失败,但后端毫无反应,还有【错误记录】ruoyi-vue@Autowired注入自定义mapper时为null解决
,感兴趣可前往观看。
实际上我后端用的是ruoyi-vue,前端用的ruoyi-app,但不重要。因为功能就是基于websocket和文心一言千帆大模型的接口,完全可以独立出来。
每个新建的账号会送一张20元的代金券,期限一个月内。而聊天服务接口单价约1分/千token,总之用来练手肯定够用了。

参考

文档中心-ERNIE-Bot-turbo
百度文心一言接入教程
若依插件-集成websocket实现简单通信

先看看效果

大致这样。
在这里插入图片描述

2023.10.13更新:昨天和朋友聊了一下,发现他的想法和我的不同——根本不用实体类去保存解析复杂的json,直接保存消息内容。有一说一,在这个小demo这里,确实可以更快更简单的实现,因为这个demo最耗时的就是看又臭又长的参数,然后写请求体和返回值的实体类,至少请求体实体类是可以不写的。

下面进入正题。

文心千帆创建应用

  1. 文心一言,大概是这里,先创建个账号,进控制台创建一个应用(有一个apikey和secretkey,有用),开通一个聊天服务(我开通的是ErnieBot-turbo),就可以了。具体有点忘了,大家可以参考其他博客。
  2. 其次官方有给一些参考,API调用指南在线测试平台,第二个链接可以对自己开通的聊天服务进行测试。其中也有一个分类是“技术文档”和“示例代码”,技术文档里边有普通/流式的请求/响应的参数和示例(如果比较小不容易看,文档中心-ERNIE-Bot-turbo也有),示例代码就是请求的各个语言的示例代码。

思路

有三个角色,大模型 ←→ 后端 ←→ 前端。

大模型:接受后端发过来的消息,返回响应消息
后端:接受前端发过来的消息,封装发给大模型;接收大模型返回的消息,回给后端;发送的消息和返回的消息都要保存到数据库
前端:发送消息,接受后端返回的响应消息,实时回显在聊天页面。

显然,websocket用在前后端之间进行交互,后端类似一个中间人,前端是一个用户,大模型是ai服务。

步骤与代码

  1. 实现websocket相关
    1.1 注册到spring
    @Configuration
    public class WebSocketConfig {
         
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
         
            return new ServerEndpointExporter();
        }
    }
    
    1.2 实现一个WebSocket的服务(别看这么长,其实参考了若依插件-集成websocket实现简单通信,但没涉及信号量之类所以没什么用,除了onMessage外,其他如onOpen打印一条消息就行了,更多如WebSocketUsers可以去链接那下载)
    @CrossOrigin
    @Component
    @ServerEndpoint("/websocket/message")
    public class WebSocketServer {
         
       private ChatRecordMapper chatRecordMapper = SpringUtils.getBean(ChatRecordMapper.class);
       /**
        * WebSocketServer 日志控制器
        */
       private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);
    
       /**
        * 默认最多允许同时在线人数100
        */
       public static int socketMaxOnlineCount = 100;
    
       private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);
    
       /**
        * 连接建立成功调用的方法
        */
       @OnOpen
       public void onOpen(Session session) throws Exception {
         
           boolean semaphoreFlag = false;
           // 尝试获取信号量
           semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
           if (!semaphoreFlag) {
         
               // 未获取到信号量
               LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
               WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制数:" + socketMaxOnlineCount);
               session.close();
           } else {
         
               // 添加用户
               WebSocketUsers.put(session.getId(), session);
               LOGGER.info("\n 建立连接 - {}", session);
               LOGGER.info("\n 当前人数 - {}", WebSocketUsers.getUsers().size());
               WebSocketUsers.sendMessageToUserByText(session, "连接成功");
           }
       }
    
       /**
        * 连接关闭时处理
        */
       @OnClose
       public void onClose(Session session) {
         
           LOGGER.info("\n 关闭连接 - {}", session);
           // 移除用户
           WebSocketUsers.remove(session.getId());
           // 获取到信号量则需释放
           SemaphoreUtils.release(socketSemaphore);
       }
    
       /**
        * 抛出异常时处理
        */
       @OnError
       public void onError(Session session, Throwable exception) throws Exception {
         
           if (session.isOpen()) {
         
               // 关闭连接
               session.close();
           }
           String sessionId = session.getId();
           LOGGER.info("\n 连接异常 - {}", sessionId);
           LOGGER.info("\n 异常信息 - {}", exception);
           // 移出用户
           WebSocketUsers.remove(sessionId);
           // 获取到信号量则需释放
           SemaphoreUtils.release(socketSemaphore);
       }
    
       /**
        * 服务器接收到客户端消息时调用的方法
        */
       @OnMessage
       public void onMessage(String message, Session session) {
         
           // 首先,接收到一条消息
           LOGGER.info("\n 收到消息 - {}", message);
           // 1. 调用大模型API,把上下文和这次问题传入,得到回复
           BigModelService bigModelService = new BigModelService();
           TurboResponse response = bigModelService.callModelAPI(session.getId(),message);
           if (response == null) {
         
               WebSocketUsers.sendMessageToUserByText(session, "抱歉,似乎出了点问题,请联系管理员");
               return;
           }
           WebSocketUsers.sendMessageToUserByText(session, response.getResult());
       }
    }
    
  2. 实现请求接口相关
    2.1 先写实体类,包括BaiduChatMessage(最基本的聊天消息)、ErnieBotTurboParam(ErnieBot-Turbo的请求参数,包括了List<BaiduChatMessage>)TurboResponse(请求返回结果对应的实体类)
    @Data
    @SuperBuilder
    @NoArgsConstructor
    @AllArgsConstructo
  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: Spring BootWebSocket实现支持简单的即时聊天应用程序的构建,可以在服务器和客户端之间双向传输消息。主要步骤如下:1. 添加WebSocket依赖 2. 实现WebSocketConfigurer接口,并重写registerWebSocketHandlers()方法 3. 编写WebSocket消息处理器 4. 测试WebSocket应用程序 ### 回答2: 实现Spring Boot中的WebSocket聊天功能代码可以按照以下步骤进行: 1. 首先,确保你的项目中已添加了相关的依赖,包括`spring-boot-starter-websocket`和`spring-boot-starter-thymeleaf`。可以在`pom.xml`中添加如下依赖: ```xml <dependencies> <!-- Spring Boot WebSocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <!-- Spring Boot Thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> ``` 2. 创建一个`WebSocketConfig`类,用于配置WebSocket: ```java import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final WebSocketHandler webSocketHandler; public WebSocketConfig(WebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler, "/chat").setAllowedOrigins("*"); } } ``` 3. 创建一个`WebSocketHandler`类,实现WebSocket的处理逻辑: ```java import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; import java.io.IOException; import java.util.ArrayList; import java.util.List; @Component public class ChatWebSocketHandler implements WebSocketHandler { private List<WebSocketSession> sessions = new ArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); } @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { for (WebSocketSession s : sessions) { s.sendMessage(new TextMessage(message.getPayload().toString())); } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { sessions.remove(session); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { session.close(); } @Override public boolean supportsPartialMessages() { return false; } } ``` 4. 创建一个`ChatController`类,用于处理聊天页面的请求: ```java import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class ChatController { @GetMapping("/chat") public String chat() { return "chat"; } } ``` 5. 创建一个`chat.html`文件,作为聊天页面的视图: ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Chat</title> </head> <body> <div id="messageContainer"></div> <script> var socket = new WebSocket("ws://" + location.host + "/chat"); socket.onmessage = function (event) { var messageContainer = document.getElementById('messageContainer'); var message = document.createElement('p'); message.innerHTML = event.data; messageContainer.appendChild(message); }; document.onkeydown = function (event) { if (event.keyCode === 13) { var input = document.querySelector('input[name="message"]'); socket.send(input.value); input.value = ''; } }; </script> </body> </html> ``` 6. 启动应用,并在浏览器中访问`http://localhost:8080/chat`,即可看到聊天页面。在多个浏览器窗口中打开该页面,它们之间可以实时互相发送消息并显示在页面上。 这是一个简单Spring Boot实现WebSocket聊天功能的代码示例,你可以根据实际需求进行调整和扩展。 ### 回答3: Spring Boot通过Spring WebSocket提供了实现WebSocket的功能。下面是实现基本聊天功能的Spring Boot WebSocket代码。 1. 创建一个Spring Boot项目,并添加以下Maven依赖到pom.xml文件中: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> </dependencies> ``` 2. 创建一个WebSocket配置类,用于配置WebSocket相关的Bean。 ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new ChatHandler(), "/chat").setAllowedOrigins("*"); } } ``` 3. 创建一个WebSocket处理程序,用于处理来自客户端的WebSocket消息。 ```java public class ChatHandler extends TextWebSocketHandler { private List<WebSocketSession> sessions = new ArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { for (WebSocketSession s : sessions) { s.sendMessage(message); } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { sessions.remove(session); } } ``` 4. 创建一个Controller类,用于处理聊天页面的请求。 ```java @Controller public class ChatController { @GetMapping("/chat") public String chat() { return "chat"; } } ``` 5. 在templates目录下创建一个chat.html文件,用于展示聊天页面。 ```html <!DOCTYPE html> <html> <head> <title>Chat</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> var socket = new WebSocket("ws://localhost:8080/chat"); socket.onmessage = function(event) { var message = event.data; $("#chat").append('<p>' + message + '</p>'); } function sendMessage() { var message = $("#message").val(); socket.send(message); $("#message").val(""); } </script> </head> <body> <input type="text" id="message"><button onclick="sendMessage()">Send</button> <div id="chat"></div> </body> </html> ``` 以上代码实现了一个简单聊天功能,客户端向服务端发送消息并显示在页面中,同时服务端将消息广播给所有客户端。通过访问http://localhost:8080/chat可以打开聊天页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值