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(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的一些常见问题。
相关文章:
SpringBoot集成websocket(5)|(使用OkHttpClient实现websocket以及详细介绍)
SpringBoot集成websocket(5)|(使用OkHttpClient实现websocket以及详细介绍) 文章目录 SpringBoot集成websocket(5)|(使用OkHttpClient实现websocket以及详细介绍)[TOC] 前言一、初始…...
Kafka-Kafka基本原理与集群快速搭建(实践)
Kafka单机搭建 下载Kafka Apache Download Mirrors 解压 tar -zxvf kafka_2.12-3.4.0.tgz -C /usr/local/src/software/kafkakafka内部bin目录下有个内置的zookeeper(用于单机) 启动zookeeper(在后台启动) nohup bin/zookeeper-server-start.sh conf…...
Elasticsearch 进阶(索引、类型、字段、分片、副本、集群等详细说明)-06
笔记来源:Elasticsearch Elasticsearch进阶 进阶-核心概念 索引Index 一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字…...
hive的分区表和分桶表详解
分区表 Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录,每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区,这样的查询效率会提高很多。 静态分区表基本语法 创建分区表 create table dept_p…...
verilog语法进阶-分布式ram
概述: FPGA的LUT查找表是用RAM设计的,所以LUT可以当成ram来使用,也并不是所有的LUT都可以当成ram来使用,sliceM的ram可以当成分布式ram来使用,而sliceL的ram只能当成rom来使用,也就是只能读,不能写&#x…...
HarmonyOS使用HTTP访问网络
HTTP数据请求 1 概述 日常生活中我们使用应用程序看新闻、发送消息等,都需要连接到互联网,从服务端获取数据。例如,新闻应用可以从新闻服务器中获取最新的热点新闻,从而给用户打造更加丰富、更加实用的体验。 那么要实现这样一种…...
GZ015 机器人系统集成应用技术样题1-学生赛
2023年全国职业院校技能大赛 高职组“机器人系统集成应用技术”赛项 竞赛任务书(学生赛) 样题1 选手须知: 本任务书共 25页,如出现任务书缺页、字迹不清等问题,请及时向裁判示意,并进行任务书的更换。参赛队…...
计算机毕业设计 基于SpringBoot的日常办公用品直售推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
uniapp:使用fixed定位,iOS平台的安全区域问题解决
manifest.json > 添加节点 "safearea": { //iOS平台的安全区域"background": "#1C1E22","backgroundDark": "#1C1E22", // HX 3.1.19支持"bottom": {"offset": "auto"} },已解决ÿ…...
三层交换机原理与配置
文章目录 三层交换机原理与配置一、三层交换技术概述二、传统的 MLS三、基于CEF 的MLS1、转发信息库(FIB)2、邻接关系表3、工作原理: 四、三层交换机的配置1、三层交换机配置命令2、三层交换机配置步骤 三层交换机原理与配置 一、三层交换技…...
Linux-----5、文件系统
# 文件系统 # 终端的基本操作 ㈠ 打开多个终端 ㈡ 快速清屏 新建标签:command T 新建窗口:command N 关闭标签:command Q 关闭窗口:command W 放大:command 缩小:command - 清屏ÿ…...
电脑自动关机怎么设置?
电脑自动关机怎么设置?如果你是一名上班族,工作忙起来很多事情都会忘记做,有时候忙到很晚后紧急下班,就会忘记给电脑关机,电脑如果经常不关机,那么电脑就会超负荷的运转,大家都知道电脑的寿命是…...
MS5602视频 8 位数模转换器,可替代TLC5602
MS5602 是低功率、超高速视频数模转换器。 MS5602 以 DC 至 20MHz 的采样速率,将数字信号转换成模拟信号。由于高速工作 的特性, MS5602 适合于数字电视、电脑视频处理及雷达信号处 理等数字视频应用。 MS5602 工作在 -40C 至 85C 的温度范围内 …...
Logistic Regression——逻辑回归
1. 为什么需要逻辑回归 在前面学习的线性回归中,我们的预测值都是任意的连续值,例如预测房价。除此之外,还有一个常见的问题就是分类问题,而逻辑回归是一个解决分类问题的模型,其预测值是离散的。 分类问题又包括…...
跟随鼠标动态显示线上点的值(基于Qt的开源绘图控件QCustomPlot进行二次开发)
本文为转载 原文链接: 采用Qt快速绘制多条曲线(折线),跟随鼠标动态显示线上点的值(基于Qt的开源绘图控件QCustomPlot进行二次开发) 内容如下 QCustomPlot是一个开源的基于Qt的第三方绘图库,能…...
Todesk、向日葵等访问“无显示器”主机黑屏问题解决
我的环境是 ubuntu 22.04 安装 要安装 video dummy,请在终端中运行以下命令: sudo apt install xserver-xorg-video-dummy配置 video dummy 的配置文件请自行搜索 使用任何文本编辑器打开此文件。 我的是 /etc/X11/xorg.conf 默认配置文件包含以下内…...
maven打包插件maven-jar-plugin与spring-boot-maven-plugin
maven几种打包插件介绍 文章目录 🔊1.spring-boot-maven-plugin打包后效果 📕2.maven-jar-plugin打包后效果🖊️最后总结 🔊1.spring-boot-maven-plugin <plugins><plugin><groupId>org.springframework.boot&…...
uniapp微信小程序下载base64图片流或https图片
常规https的图片下载是这样的 const urlPath https://test/logo.png uni.downloadFile({url: urlPath,success(res){// 这时会产生一个临时路径,在应用本次启动期间可以正常使用。if (res.statusCode 200) {// 需要将图片保存到相册uni.saveImageToPhotosAlbum({…...
数据结构 | Log-Structured Merge Tree (LSM Tree)
今天介绍LSM Tree这个数据结构,严格意义上来说,他并不像他的名字一样是一棵树型的数据结构,而更多是一种设计思想。 LSM Tree最先在1996年被提出,后来被广泛运用于现代NoSQL(非关系型数据库)系统中…...
QEMU源码全解析 —— virtio(9)
接前一篇文章: 上两回讲解了virtio balloon相关类所涉及的realize函数以及大致流程,如下表所示: realize函数parent_dc_realize函数DeviceClassvirtio_pci_dc_realizePCIDeviceClassvirtio_pci_realizeVirtioPCIClassvirtio_balloon_pci_rea…...
金蝶云星空协同开发环境应用内执行单据类型脚本
文章目录 金蝶云星空协同开发环境应用内执行单据类型脚本业务界面查询单据类型表数据导出数据执行数据库脚本单据类型xml检验是否执行成功检查数据库检查业务数据 金蝶云星空协同开发环境应用内执行单据类型脚本 业务界面 查询单据类型表数据 先使用类型中文在单据类型多语言…...
矩阵理论及其应用邱启荣习题3.5题解
(1) P ( − 1 0 1 − 1 − 1 2 1 1 − 1 ) \begin{pmatrix} -1 & 0&1 \\ -1 & -1&2\\1&1&-1 \end{pmatrix} −1−110−1112−1 A ( 1 0 1 1 1 0 − 1 2 1 ) \begin{pmatrix} 1 & 0&1 \\ 1 & 1&0\\-1&2&1 \end{pmat…...
Java面试题(每天10题)-------连载(49)
目录 Tomcat篇 1、Tomcat的缺省端口是多少?怎么修改? 2、Tomcat有哪几种Connector运行模式(优化)? 3、Tomcat有几种部署方式? 4、Tomcat容器时如何创建servlet类实例?用到了什么原理&…...
python——数据类型
数据类型目录 前言一、Number(数字)数字类型转换:二、String(字符串)常用字符串运算符:字符串格式化:三、Tuple(元组)常用运算符四、List(列表)嵌套列表:常用列表操作:五、Dictionary(字典)六、Set(集合)...
hive中如何求取中位数?
目录 中位数的概念代码实现准备数据实现 中位数的概念 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本、种群或概率分布中的一个数值,其可将数值集合…...
在C#中异步编程
在C#中,异步编程是一种编写并发和响应式代码的技术,通过将耗时的操作放在后台线程中执行,以避免阻塞主线程,提高程序的性能和响应性。异步编程使用async和await关键字,结合任务(Task)和异步操作…...
微服务保护--Feign整合Sentinel
限流是一种预防措施,虽然限流可以尽量避免因高并发而引起的服务故障,但服务还会因为其它原因而故障。而要将这些故障控制在一定范围,避免雪崩,就要靠线程隔离(舱壁模式)和熔断降级手段了。 线程隔离之前讲到…...
二进制to十六进制
输入小于等于十六位的二进制数据,输出十六进制数据; #include <stdio.h> #include <stdlib.h> #include <math.h>int main(void) {char arr[16] { 0 }; int array[16] { 0 }; int hex[4] { 0 };int i 0; int num 0;scanf("…...
Logistic 回归算法
Logistic 回归 Logistic 回归算法Logistic 回归简述Sigmoid 函数Logistic 回归模型表达式求解参数 $\theta $梯度上升优化算法 Logistic 回归简单实现使用 sklearn 构建 Logistic 回归分类器Logistic 回归算法的优缺点 Logistic 回归算法 Logistic 回归简述 Logistic 回归是一…...
ubuntu安装详细步骤
一,先下载vmware 1,第一步打开上面链接 下载网址 : https://www.vmware.com/products/workstation-pro/wo rkstation-pro-evaluation.html 许可证 JU090-6039P-08409-8J0QH-2YR7F ZF3R0-FHED2-M80TY-8QYGC-NPKYF FC7D0-D1YDL-M8DXZ-CYPZE-P2AY6 ZC3T…...
微信的微网站模板下载不了/淘客推广怎么做
王姐手下,经营着一个女装店,有5、6年了。手上有不少老客户,但是生意一直不温不火,平平淡淡。赔钱不至于,但是发不了财。 她店里的女装,进货价在300到600之间,卖价1000多2000,利润空…...
wordpress自定义文章添加标签/公司官网制作多少钱
使用yum安装epel yum源,并安装nginx1、安装epel-release2、yum repolist3、查看 epel repo4、安装 nginx5、启动 nginx 服务6、web 进行访问1、安装epel-release [rootNeo_Tang ~]# yum install epel-release -y Loaded plugins: fastestmirror Loading mirror spe…...
学校网站 功能/全国新闻媒体发稿平台
物联网时代,拼的是生态。 6月23日下午,海尔宣布开放U智慧生活平台的SDK软件包,它为开发者搭建的开放的开发平台“海极网”2.0正式上线,以整合更多的生态资源。 海尔U推广总监邹峘浩表示,智能家居概念在前两年被爆炒&am…...
b2c网站建设费用/新闻 最新消息
要说生科的水还是很深的,找个耗材、试剂总是被坑的事件屡见不鲜了!所以很多人明白了一个道理,图便宜没好货,找好货还得找大牌!就像胎牛血清(FBS),可以说是我们科研里比较常用&#x…...
务川网站建设wguser/互联网营销师培训学校
成绩分析问题_m0_59519985的博客-CSDN博客 饮料换购问题_m0_59519985的博客-CSDN博客 刷题统计(注意类型)_m0_59519985的博客-CSDN博客 天干地支(Java)_m0_59519985的博客-CSDN博客 递增序列: 题目描述 本题为填…...
网站开发流程的认识/大数据分析师
问题描述见:http://www.iteye.com/problems/87448 Struts2里面的Action对象的result的String Print出来的结果没有问题 {"id":"4028efd439422d260139422d2a530000","name":"department"} 在Struts.xml里面配置的 <package name&quo…...