SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)
SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)
文章目录
- SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)
- @[TOC]
- 前言
- 一、websocket服务端依赖引入
- 二、websocket服务代码实现
- 1.WebSocketConfig配置
- 2.WebSocketServer服务实现
- 3.ChatClient4Chat连接工具实现
- 3.WebSocketClient连接第三方客户端实现
- 总结
文章目录
- SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)
- @[TOC]
- 前言
- 一、websocket服务端依赖引入
- 二、websocket服务代码实现
- 1.WebSocketConfig配置
- 2.WebSocketServer服务实现
- 3.ChatClient4Chat连接工具实现
- 3.WebSocketClient连接第三方客户端实现
- 总结
章节
第一章链接: SpringBoot集成websocket(1)|(websocket客户端实现)
第二章链接: SpringBoot集成websocket(2)|(websocket服务端实现以及websocket中转实现)
前言
本节主要介绍的是springboot实现websocket的客户端服务端,以及客户端与服务端的数据互传。以下为伪代码,业务逻辑删除导致不能直接拷贝运行,大家可以参考其中的思路实现。
一、websocket服务端依赖引入
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
二、websocket服务代码实现
1.WebSocketConfig配置
springboot接入websocket需要启用对应的配置
@Configuration
@EnableWebSocket
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}
2.WebSocketServer服务实现
springboot提供对外的websocket接口实现
@Component
@Data
@Slf4j
@ServerEndpoint(value = "/v1/chat")
public class DocChatServer {public final static String CHAT_ERR_MSG_FORMAT = "{\"header\":{\"code\":10001,\"message\":\"参数格式不对\",\"sId\":\"%s\",\"status\":2}}";@Autowiredprivate void setOriginMessageSender() {// 初始化注入bean 隐藏掉了}@OnOpenpublic void OnOpen(Session session) {log.debug("chat websocket open ");}@OnClosepublic void OnClose() {log.debug("chat websocket close ");}@OnMessagepublic void OnMessage(Session session, String message) {SearchDocParamVo param = null;log.debug("ApiRequest = {}", message);// 参数校验try {JSONObject jsonObject = JSONObject.parseObject(message);// todo 参数校验} catch (Exception e) {String errMsg = String.format(CHAT_ERR_MSG_FORMAT, session.getId());log.error("chat请求参数格式不会:{},异常:{}", errMsg, e);send(session, errMsg);return;}// todo 业务处理List<ChatRecord.Source> sources = Lists.newArrayList();;String prompt = "";// 谈话接口queryChat(session, param, prompt, sources);}/*** 执行谈话** @param session* @param param* @param prompt* @param sources*/private void queryChat(Session session, SearchDocParamVo param, String prompt, List<ChatRecord.Source> sources) {// todo 业务处理 。。。// 消息发送try {boolean b = this.sendChatMessage(session, param, sources, texts);if (!b) {List<Text> textsTry = Lists.newArrayList();Text build1 = Text.builder().role("user").content("请更具自己的理解回答问题:" + param.getContent()).build();textsTry.add(build1);this.sendChatMessage(session, param, sources, textsTry);}} catch (Exception e) {log.error("发送消息异常:{}", e.getMessage());}}/*** 收到谈话响应数据处理** @param session* @param param* @param sources* @param texts* @return*/private boolean sendChatMessage(Session session, SearchDocParamVo param, List<ChatRecord.Source> sources, List<Text> texts) {ChatClient4Chat planetClient4Chat = new ChatClient4Chat(websocketConfigConst);try {planetClient4Chat.send(param, texts, new ApiResponseObserver() {public void onReceive(String message) {// 收到远程websocket服务响应的数据}public void onError(Throwable throwable) {log.error("收到错误:{}", throwable);}public void onCompleted() {log.error("收到结束");}});// 以下是业务逻辑 可忽略for (int i = 0; i < 100; i++) {if (planetClient4Chat.isHasCheck()) {log.debug("has check");return planetClient4Chat.isSuccess();} else {Thread.sleep(500);}}} catch (Exception e) {log.error("发送消息异常:{}", e.getMessage());}return true;}public void send(Session session, String msg) {synchronized (session) {if (!session.isOpen()) {log.error("客户端连接关闭,数据不发送:{}", msg);return;}try {session.getBasicRemote().sendText(msg);} catch (IOException ex) {log.error("传递消息给客户端异常:{}", ex.getMessage());}}}public int getStatus(String message) {int status = -1;try {//todo 业务逻辑return choices.getStatus();} catch (Exception e) {log.error("数据中提取status异常:{}", e);}return status;}@OnErrorpublic void onerror(Session session, Throwable throwable) {log.error("chat连接异常关闭:远程主机强迫关闭了一个现有的连接:{}", throwable);}}
3.ChatClient4Chat连接工具实现
springboot提供对中间衔接工具了,连接第三饭websocket接口
实现代码如下
@Slf4j
@Getter
@Setter
public class ChatClient4Chat {private static WebsocketConfigConst websocketConfigConst;private StringBuilder stringBuilder;private boolean hasCheck;private boolean success;private Queue<String> queue;private ChatChatServer sparkChatServer;ChatClient4Chat(WebsocketConfigConst websocketConfigConst) {this.websocketConfigConst = websocketConfigConst;this.stringBuilder = new StringBuilder();this.hasCheck = false;this.success = true;this.queue = new LinkedList<String>();}/*** 执行聊天** @param param*/public void send(SearchDocParamVo param, List<Text> texts, ApiResponseObserver apiResponseObserver) {// 获取连接ChatChatServer chatServer = (ChatChatServer ) getWebSocketClient(apiResponseObserver);if (chatServer != null && chatServer.isOpen()) {this.sparkChatServer = chatServer;// 消息发送try {chatServer.send(SparkHand.initParam(param, texts, websocketConfigConst.type, websocketConfigConst.appid, websocketConfigConst.token));} catch (Exception e) {log.error("发送消息异常:{}", e.getMessage());}} else {log.error("接口连接未打开");}}public void close() {// 获取连接if (sparkChatServer != null && sparkChatServer.isOpen()) {sparkChatServer.close();} else {log.error("接口连接未打开,关闭异常");}}private void waitConnect() {try {Thread.sleep(50);} catch (InterruptedException e) {log.error("等待连接异常");}}private WebSocketClient getWebSocketClient(ApiResponseObserver apiResponseObserver) {WebSocketClient client = new SparkChatServer(websocketConfigConst.chaturl, apiResponseObserver);client.connect();waitConnect();return client;}
}
ApiResponseObserver 是一个定义的接口,规范一些方法
public interface ApiResponseObserver extends ResponseObservable<String> {
}public interface ResponseObservable<T> {void onReceive(T response);void onError(Throwable throwable);void onCompleted();
}
3.WebSocketClient连接第三方客户端实现
springboot提供对第三方websocket连接的客户端
实现代码如下
@Slf4j
public class SparkChatServer extends WebSocketClient {private ApiResponseObserver apiResponseObserver;public SparkChatServer(URI serverUri, ApiResponseObserver apiResponseObserver) {super(serverUri);this.apiResponseObserver = apiResponseObserver;}@Overridepublic void onOpen(ServerHandshake serverHandshake) {log.debug("chat 服务连接成功");}@Overridepublic void onMessage(String message) {log.debug("收到chat数据{}", message);apiResponseObserver.onReceive(message);}@Overridepublic void onClose(int i, String s, boolean b) {log.debug("退出chat连接");}@Overridepublic void onError(Exception e) {log.error("chat连接出现异常:{}", e);}
}
总结
本文主要介绍websocket客户端、服务端的实现,同时通过连接工具中转websocket请求参数,捉到实时同步,以及数据收集。代码为伪代码,删除了实际使用当中的业务逻辑,介绍的是实现实录,大家可以参考。
第一章链接: SpringBoot集成websocket(1)|(websocket客户端实现)
第二章链接: SpringBoot集成websocket(2)|(websocket服务端实现以及websocket中转实现)
相关文章:
SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)
SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传) 文章目录 SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)[TOC] 前…...

基于Doris实时数据开发的一些注意事项
300万字!全网最全大数据学习面试社区等你来! 最近Doris的发展大家是有目共睹的。例如冷热分离等新特性的持续增加。使得Doris在易用和成本上都有大幅提升。 基于Doris的一些存储实时数仓在越来越多的场景中开始有一些实践。大家也看到了这种方案频繁出现…...

竞赛项目 深度学习疲劳驾驶检测 opencv python
文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 🔥 优…...

20.4 HTML 表单
1. form表单 <form>标签: 用于创建一个表单, 通过表单, 用户可以向网站提交数据. 表单可以包含文本输入字段, 复选框, 单选按钮, 下拉列表, 提交按钮等等. 当用户提交表单时, 表单数据会发送到服务器进行处理.action属性: 应指向一个能够处理表单数据的服务器端脚本或UR…...

Linux——基础IO(1)
目录 0. 文件先前理解 1. C文件接口 1.1 写文件 1.2 读文件 1.3 输出信息到显示器 1.4 总结 and stdin & stdout & stderr 2. 系统调用文件I/O 2.1 系统接口使用示例 2.2 接口介绍 2.3 open函数返回值 3. 文件描述符fd及重定向 3.1 0 & 1 & 2 3.2…...

MFC第二十七天 通过动态链表实现游戏角色动态增加、WM_ERASEBKGND背景刷新的原理、RegisterClass注册窗口与框架程序开发
文章目录 通过动态链表实现游戏角色动态增加CMemoryDC.hCFlashDlg.hCFlashDlg.cpp WM_ERASEBKGND背景刷新的原理RegisterClass注册窗口与框架程序开发CFrameRegister 通过动态链表实现游戏角色动态增加 CMemoryDC.h #pragma once#include "resource.h"/*内存DC类简介…...
Debezium系列之:基于内容路由实现把数据库表中的数据按照数据类型分发到不同的topic
Debezium系列之:基于内容路由实现把数据库表中的数据按照数据类型分发到不同的topic 一、需求背景二、创建表三、插入、更新、删除数据四、核心参数和实现技术五、查看分发的Topic六、消费Topic数据七、总结和延展一、需求背景 一张表中存有各个超市门店的订单信息,例如超市门…...
苹果账号被禁用怎么办?
苹果账号被禁用怎么办? 转载:苹果账号被禁用怎么办? 当我们使用苹果手机登录App Store时,有时会遇到账号被禁用的提示。总结下来, 账号被禁用的原因可能有以下几种: 禁用的原因 1.在不同的设备上登录Ap…...
文章一:快速上手Git - 从零到一:Git版本控制入门指南
开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。 概述 在软件开发和团队协作中,版本控制是一项至关重要的技术。Git作为现代开发者最喜爱的版本控…...

【用unity实现100个游戏之6】制作一个战旗自走棋类游戏(附源码)
文章目录 前言导入素材开始1. 设置瓦片间隙2. 放置全图瓦片3. 美化瓦片地图4. 添加树木障碍物5. 设定不同的排序图层6. 瓦片交互6. 瓦片交互优化6. 瓦片是否允许角色7. 添加角色8. 新增游戏管理脚本9. 角色移动范围逻辑10. 角色移动范围可视化11. 角色移动12. 重置瓦片颜色12. …...

W5100S-EVB-PICO 做TCP Server进行回环测试(六)
前言 上一章我们用W5100S-EVB-PICO开发板做TCP 客户端连接服务器进行数据回环测试,那么本章将用开发板做TCP服务器来进行数据回环测试。 TCP是什么?什么是TCP Server?能干什么? TCP (Transmission Control Protocol) 是一种面向连…...

dinput8.dll导致游戏打不开的解决方法,快速修复dinput8.dll文件
当你尝试启动某个游戏时,如果遇到dinput8.dll文件缺失或损坏的错误提示,可能会导致游戏无法正常运行。dinput8.dll是DirectInput API的一部分,它提供了游戏手柄、键盘和鼠标等输入设备的支持。本文将详细介绍dinput8.dll的作用、导致游戏无法…...
NAS相关
Debian11 更换软件源 备份 #备份软件源列表 cp /etc/apt/sources.list /etc/apt/sources.list.bak编辑sources.list nano /etc/apt/sources.list替换文件内容 deb http://mirrors.163.com/debian/ bullseye main non-free contrib deb http://mirrors.163.com/debian/ bull…...
26.Netty源码之ThreadLocal
highlight: arduino-light JDK ThreadLocal 如果你需要变量在多线程之间隔离,或者在同线程内的类和方法中共享,那么 ThreadLocal 大显身手的时候就到了。ThreadLocal 可以理解为线程本地变量,它是 Java 并发编程中非常重要的一个类。 ThreadL…...

Mysql SUBSTRING_INDEX - 按分隔符截取字符串
作用: 按分隔符截取字符串 语法: SUBSTRING_INDEX(str, delimiter, count) 属性: 参数说明str必需的。一个字符串。delimiter必需的。分隔符定义,是大小写敏感,且是多字节安全的count必须的。大于0或者小于0的数值…...

封装Ellipsis组件,亲测使用各种场景
自己封装了Ellipsis组件 基于reacttaro,以下是实现代码,分为JSX和CSS文件 JSX代码如下: import { FC, Fragment, JSX, useState } from react; import { Image, StandardProps, Text, View } from tarojs/components;import iconDropDown fr…...

Kendo UI for jQuery,一个现代的jQuery UI组件!
Kendo UI for jQuery是什么? Kendo UI for jQuery是完整的jQuery UI组件库,可快速构建出色的高性能响应式Web应用程序。Kendo UI for jQuery提供在短时间内构建现代Web应用程序所需要的工具,从多个UI组件中选择,并轻松地将它们组…...

C++初阶语法——类和对象
前言:C语言中的结构体,在C有着更高位替代者——类。而类的实例化叫做对象。 本篇文章不定期更新扩展后续内容。 目录 一.面向过程和面向对象初步认识二.类1.C中的结构体2.类的定义类的两种定义方式 3.类的访问限定符及封装访问限定符说明 4.类的实例化对…...

linux学习(进程创建)[8]
创建进程 myproc.c #include <stdio.h> #include <unistd.h>int main() {printf("我是父进程\n");pid_t id fork();if(id < 0){printf("创建子进程失败\n");return 1;}else if(id 0){while(1){printf("我是子进程: pid…...

Linux基础与应用开发系列九:各类系统函数
open_close函数 OPEN函数 头文件: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> 函数原型: 当文件存在时 int open(const char* pathname,int flags) 当文件不存在时 int open (const char* pathname,int f…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...