当前位置: 首页 > news >正文

SpringBoot集成websocket(5)|(使用OkHttpClient实现websocket以及详细介绍)

SpringBoot集成websocket(5)|(使用OkHttpClient实现websocket以及详细介绍)


文章目录

  • SpringBoot集成websocket(5)|(使用OkHttpClient实现websocket以及详细介绍)
    • @[TOC]
  • 前言
  • 一、初始化OkHttpClient
    • 1.OkHttpClient实现
  • 二、websocket服务代码实现
    • 1.websocket服务端实现
    • 2.SparkClient4Chat 实现
  • 三、websocket客户端代码实现
    • 3.SparkChatServer实现
  • 总结

章节
第一章链接: SpringBoot集成websocket(1)|(websocket客户端实现)
第二章链接: SpringBoot集成websocket(2)|(websocket服务端实现以及websocket中转实现)
第三章链接: SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)
第四章链接: SpringBoot集成websocket(4)|(使用okhttp3实现websocket)
第五章链接: SpringBoot集成websocket(5)|(使用OkHttpClient实现websocket以及详细介绍)

前言

上篇文章介绍了为什么选用OkHttpClient来实现websocket,本篇章就不过多的讲述,本章主要介绍OkHttpClient实现websocket多级代理跳转中的问题优化以及springboot实现websocket的一些常见问题。

一、初始化OkHttpClient

每个client对象都有自己的线程池和连接池,如果为每个请求都创建一个client对象,自然会出现内存溢出。所以官方建议OkHttpClient应该单例化,重用连接和线程能降低延迟和减少内存消耗。

1.OkHttpClient实现

官方介绍了三种创建client的方式
1、new OkHttpClient()
该方式将创建一个使用默认设置的client单例对象。
2、new OkHttpClient.Builder()
该方式允许自定义配置自己的单例client对象。配置connectionTimeout, readTimeout, writeTimeout等参数。
3、okHttpclient.newBuilder()
该方式通过已经存在的client对象,创建特殊需要的client对象。如 我们通过上个方法创建了自定义配置的单例client对象,但是针对某些场景需要调整某些参数,那么就需要使用该方法创建定制的client。新client对象与旧client对象共享连接池,线程池和其他配置。

    @Beanpublic OkHttpClient getOkHttpClient() {return new OkHttpClient.Builder().connectTimeout(50L, TimeUnit.SECONDS)  // 超时连接时间.readTimeout(3*60L, TimeUnit.SECONDS)  // 超速读取时间.build();}

二、websocket服务代码实现

依赖上篇文章已经介绍过现在不做介绍

1.websocket服务端实现

springboot 服务端代码实现,用于给前端进行连接

@Component
@Data
@Slf4j
@ServerEndpoint(value = "/v1/chat")
public class DocChatServer {// 注意 此处定义的为静态变量,原因是ServerEndpoint 是多例的,不能用springBoo直接注入容器里的对象,static前提是变量都需要是单例,多例的话会有线程安全问题private static SparkClient4ChatBuild sparkClient4ChatBuild;private static OkHttpClient httpClient;@Autowiredprivate void setOriginMessageSender(SparkClient4ChatBuild sparkClient4ChatBuild,OkHttpClient httpClient) {log.debug("客户端连接 A chat 初始化");this.sparkClient4ChatBuild = sparkClient4ChatBuild;this.httpClient = httpClient;}@OnOpenpublic void OnOpen(Session session) {log.debug("客户端连接 A chat 接口");}@OnClosepublic void OnClose() {log.debug("---客户端关闭 A chat 接口");
//        log.info("结束调用cancel");
//        planetClient4Chat.cancel();}@OnErrorpublic void onError(Session session, Throwable t) {log.debug("---客户端连接 A chat 接口异常");t.printStackTrace();}@OnMessagepublic void OnMessage(Session session, String message) {log.debug("客户端连接 A chat 进行中");boolean b = sendGptMessage(session, message);log.debug("客户端连接 A chat 结束:{}", b);}/*** 收到gpt型响应数据处理** @param session 会话id* @return*/private boolean sendGptMessage(Session session, String message) {SparkClient4Chat planetClient4Chat = sparkClient4ChatBuild.build();// 连接第三方ws地址planetClient4Chat.connect(new ApiResponseObserver() {public void onReceive(String message) {log.debug("收到响应数据:{}", message);JsonParse jsonMessage = JSON.parseObject(message).toJavaObject(JsonParse.class);if (jsonMessage.header.status == 2) {try {log.info("运行中调用cancel");planetClient4Chat.cancel();} catch (Exception e) {throw new RuntimeException(e);}}}public void onError(Throwable throwable) {log.debug("会话异常:{}", throwable.getMessage());}public void onCompleted() {log.error("回调收到结束");}});//String messages2 = "{\"讲一个故事\"}";planetClient4Chat.send(message);return true;}}

注意:websocket 是多对象的,每个用户的聊天客户端对应 java 后台的一个 websocket 对象,前后台一对一(多对多)实时连接,所以 websocket 不可能像 servlet 一样做成单例的,让所有聊天用户连接到一个 websocket对象,这样无法保存所有用户的实时连接信息。可能 spring 开发者考虑到这个问题,没有让 spring 创建管理 websocket ,而是由 java 原来的机制管理websocket ,所以用户聊天时创建的 websocket 连接对象不是 spring 创建的,spring 也不会为不是他创建的对象进行依赖注入,所以如果不用static关键字,每个 websocket 对象的 service 都是 null

2.SparkClient4Chat 实现

用于处理第三方chat连接


@Slf4j
@Getter
@Setter
public class SparkClient4Chat {String chatUrl = "ws://xxx/v2.1/chat";private WebSocket webSocket;public void connect(OkHttpClient okHttpClient, ApiResponseObserver apiResponseObserver) {Request request = new Request.Builder().url(url).build();SparkChatServer sparkChatServer = new SparkChatServer(apiResponseObserver);this.webSocket = okHttpClient.newWebSocket(request, sparkChatServer);}public void send(String message) {log.debug("ApiRequest = {}", message);this.webSocket.send(message);}public void cancel() {log.debug("cancel begin...");if (this.webSocket != null) {this.webSocket.cancel();  // cancel暴力关闭(立马见效),用close是不能立马关闭的,管道中的数据还会持续发送过来this.webSocket = null;log.debug("cancel end.");}}public void close() throws Exception {log.debug("close begin...");if (this.webSocket != null) {log.debug("this.webSocket.close(1000, \"NORMAL_CLOSURE\")");this.webSocket.close(1000, "NORMAL_CLOSURE");this.webSocket = null;log.debug("close end...");}}
}

三、websocket客户端代码实现

主要用来连接第三方ws介绍

3.SparkChatServer实现

用于处理第三方chat连接 ,通过回调函数直接放回信息给客户端的连接


@Slf4j
public class SparkChatServer extends WebSocketListener {private ApiResponseObserver apiResponseObserver;public SparkChatServer(ApiResponseObserver apiResponseObserver) {this.apiResponseObserver = apiResponseObserver;}@Overridepublic void onOpen(WebSocket webSocket, Response response) {super.onOpen(webSocket, response);log.debug("连接GPT大模型");}@Overridepublic void onMessage(WebSocket webSocket, String message) {apiResponseObserver.onReceive(message);}@Overridepublic void onFailure(WebSocket webSocket, Throwable t, Response response) {apiResponseObserver.onError(t);log.error("chat连接出现异常:{}", t.getMessage());}
}

总结

本文主要介绍了为什么选用OkHttpClient来实现websocket,本篇章就不过多的讲述,本章主要介绍OkHttpClient实现websocket多级代理跳转中的问题优化以及springboot实现websocket的一些常见问题。

http://www.lryc.cn/news/260749.html

相关文章:

  • Kafka-Kafka基本原理与集群快速搭建(实践)
  • Elasticsearch 进阶(索引、类型、字段、分片、副本、集群等详细说明)-06
  • hive的分区表和分桶表详解
  • verilog语法进阶-分布式ram
  • HarmonyOS使用HTTP访问网络
  • GZ015 机器人系统集成应用技术样题1-学生赛
  • 计算机毕业设计 基于SpringBoot的日常办公用品直售推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解
  • uniapp:使用fixed定位,iOS平台的安全区域问题解决
  • 三层交换机原理与配置
  • Linux-----5、文件系统
  • 电脑自动关机怎么设置?
  • MS5602视频 8 位数模转换器,可替代TLC5602
  • Logistic Regression——逻辑回归
  • 跟随鼠标动态显示线上点的值(基于Qt的开源绘图控件QCustomPlot进行二次开发)
  • Todesk、向日葵等访问“无显示器”主机黑屏问题解决
  • maven打包插件maven-jar-plugin与spring-boot-maven-plugin
  • uniapp微信小程序下载base64图片流或https图片
  • 数据结构 | Log-Structured Merge Tree (LSM Tree)
  • QEMU源码全解析 —— virtio(9)
  • 金蝶云星空协同开发环境应用内执行单据类型脚本
  • 矩阵理论及其应用邱启荣习题3.5题解
  • Java面试题(每天10题)-------连载(49)
  • python——数据类型
  • hive中如何求取中位数?
  • 在C#中异步编程
  • 微服务保护--Feign整合Sentinel
  • 二进制to十六进制
  • Logistic 回归算法
  • ubuntu安装详细步骤
  • 力扣5. 最长回文子串