当前位置:   article > 正文

使用websocket后端接入文心一言

使用websocket后端接入文心一言

最近再写项目练手,想着最近大模型那么火,也想接入项目来玩一玩,于是去了解了一下相关的api和通信协议,最后选择了文心一言进行集成,国内的相对稳定。ERNIE-Bot-turbo - 千帆大模型平台 | 百度智能云文档 (baidu.com)

使用websocket进行双向通信,因为http是单向协议显然不适合这样的场景。简单介绍一下websocket它是一个双向的通信协议,一旦通信双方建立联系,就可以互相发送消息。

 

http和websocket通信过程图

现在就开始进行配置吧,首先我们需要配置好websocket的的相关依赖已经配置serverEndpoint的扫描。

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-websocket</artifactId>
  4. </dependency>
  1. @Configuration
  2. public class WebSocketConfig
  3. {
  4. @Bean
  5. public ServerEndpointExporter serverEndpointExporter()
  6. {
  7. return new ServerEndpointExporter();
  8. }
  9. }

如此就将准备工作做好了,现在配置一下访问处理的server

  1. @Component
  2. @ServerEndpoint("/websocket/message")
  3. public class WebSocketServer
  4. {
  5. /**
  6. * 实现日志打印
  7. */
  8. private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);
  9. public static int socketMaxOnlineCount = 100;
  10. private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);
  11. private List<BaiduChatMessage> userMessage[]=new List[2000];
  12. /**
  13. * 连接建立成功调用的方法
  14. */
  15. @OnOpen
  16. public void onOpen(Session session) throws Exception
  17. {
  18. SemaphoreUtils.tryAcquire(socketSemaphore);
  19. LOGGER.info("\n 成功连接 - {}", session);
  20. }
  21. /**
  22. * 连接关闭时处理
  23. */
  24. @OnClose
  25. public void onClose(Session session)
  26. {
  27. LOGGER.info("\n 关闭连接 - {}", session);
  28. // 获取到信号量则需释放
  29. SemaphoreUtils.release(socketSemaphore);
  30. }
  31. /**
  32. * 抛出异常时处理
  33. */
  34. @OnError
  35. public void onError(Session session, Throwable exception) throws Exception
  36. {
  37. if (session.isOpen())
  38. {
  39. // 关闭连接
  40. session.close();
  41. }
  42. String sessionId = session.getId();
  43. LOGGER.info("\n 连接异常 - {}", sessionId);
  44. LOGGER.info("\n 异常信息 - {}", exception);
  45. // 获取到信号量则需释放
  46. SemaphoreUtils.release(socketSemaphore);
  47. }
  48. /**
  49. * 服务器接收到客户端消息时调用的方法
  50. */
  51. @OnMessage
  52. public void onMessage(String message, Session session) throws IOException {
  53. // 首先,接收到一条消息
  54. LOGGER.info("\n 收到消息 - {}", message);
  55. // 1. 调用大模型API,把上下文和这次问题传入,得到回复
  56. BigModelService bigModelService = new BigModelService();
  57. boolean f = bigModelService.callModelAPI(session,message,userMessage);
  58. if (!f) {
  59. session.getBasicRemote().sendText("抱歉,似乎出了点问题,请联系管理员");
  60. return;
  61. }
  62. }
  63. }

都使用注解进行控制,其中这里最重要的就是 OnMessage,这个是得到websocket消息进行的处理,是最核心的方法,本次主要的业务实现焦距于本方法。

接下来就是将问题发送给文心一言的接口然后得到回应了

下面粘贴一下主代码

  1. public boolean callModelAPI(Session session, String message, Map<String,List<BaiduChatMessage>> userMassage) {
  2. String records = "{}";
  3. ErnieBotTurboParam param = JSONObject.parseObject(records, ErnieBotTurboParam.class);
  4. //未将信息存入数据库,使用会话做一个简单的持久化
  5. if(userMassage.get(session.getId()) == null)
  6. userMassage.put(session.getId(),new ArrayList<>());
  7. //存入最新消息
  8. userMassage.get(session.getId()).add(BaiduChatMessage.builder().role("user").content(message).build());
  9. // 1.2.2 把messages重新设置到param中
  10. param.setMessages(userMassage.get(session.getId()));
  11. try {
  12. // 2. 发出请求,调用大模型API
  13. RequestBody body = RequestBody.create(MediaType.parse("application/json"), JSONObject.toJSONString(param));
  14. Request request = new Request.Builder()
  15. .url("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token=" + getAccessToken())
  16. .method("POST", body)
  17. .addHeader("Content-Type", "application/json")
  18. .build();
  19. Response response = HTTP_CLIENT.newCall(request).execute();
  20. if (response.isSuccessful()) {
  21. //对返回信息进行处理
  22. try (ResponseBody responseBody = response.body()) {
  23. if (responseBody != null) {
  24. InputStream inputStream = responseBody.byteStream();
  25. // 以流的方式处理响应内容
  26. byte[] buffer = new byte[2048];
  27. int bytesRead;
  28. String ss="";
  29. while ((bytesRead = inputStream.read(buffer)) != -1) {
  30. // 在控制台输出每个数据块
  31. String s[] = new String(buffer, 0, bytesRead).split("data: ");
  32. int n=1;
  33. while (n<s.length) {
  34. System.out.println(s[n]);
  35. TurboResponse turboResponse = JSONObject.parseObject(s[n++], TurboResponse.class);
  36. ss+=turboResponse.getResult();
  37. session.getBasicRemote().sendText(turboResponse.getResult());
  38. }
  39. }
  40. userMassage.get(session.getId()).add(BaiduChatMessage.builder().role("assistant").content(ss).build());
  41. }
  42. }
  43. return true;
  44. } else {
  45. LOGGER.error("调用大模型API失败: {}", response.message());
  46. }
  47. } catch (IOException e) {
  48. LOGGER.error("调用大模型API发生异常:", e);
  49. }
  50. return false;
  51. }

如此便实现了基本的通信服务,下面来看看效果

 

效果只能说够用 ,也还不错吧。

期待这篇文章可以帮助到大家

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/82758
推荐阅读
相关标签
  

闽ICP备14008679号