Springboot使用事件流调用大模型接口
什么是事件流
事件流(Event Stream) 是一种处理和传递事件的方式,通常用于系统中的异步消息传递或实时数据流。在事件驱动架构(Event-Driven Architecture)中,事件流扮演着至关重要的角色。
事件流的概念:
-
事件(Event):
事件是指系统中的某个状态变更或者操作的发生。例如,用户点击按钮、订单创建、传感器检测到的温度变化等都可以视为事件。 -
事件流(Event Stream):
事件流是指一系列有序的事件,这些事件按照时间顺序传输并可能被处理。事件流是一个数据流,它将事件按顺序传递给系统中的不同组件或服务。 -
流的特性:
- 时间序列:事件流通常按照时间顺序传递,也就是说,先发生的事件会先传递。
- 异步性:事件流通常是异步的,意味着事件的生产者和消费者之间不一定同步工作,消费者可以在稍后的时间消费事件。
- 连续性:事件流是一个连续的过程,事件会不断地产生并被处理。
事件流的应用场景:
-
日志流:
在现代分布式系统中,日志通常会以事件流的形式处理和传输。例如,系统的操作、错误或者状态变更会作为事件记录下来,并通过事件流传输到日志收集和分析系统中。 -
实时数据处理:
事件流在实时数据处理场景中非常重要,比如流式处理框架(例如Apache Kafka、Apache Flink等)就是用于处理不断产生的事件流。这些流可以表示实时的交易、用户活动、传感器数据等。 -
消息传递:
在消息队列系统中,消息也可以被视为事件流的一部分。生产者发布消息(事件),消费者接收并处理这些消息。 -
事件驱动架构(EDA):
在事件驱动架构中,系统的各个组件通过事件进行通信。每当一个事件发生时,系统的某个部分会被触发并响应这些事件。
事件流与传统流的不同:
- 传统流:通常是指一系列数据或任务的流转,它通常是在一定的顺序和时间点进行处理。
- 事件流:是一种更加灵活的流动方式,侧重于异步传递、处理和反应的模式。事件流中的每个事件通常是独立的、无状态的,并且具有明确的触发条件。
事件流的优势:
- 解耦:生产者和消费者之间通过事件流进行通信,从而降低了系统组件之间的耦合度。
- 扩展性:可以通过增加事件消费者来横向扩展系统处理能力。
- 实时性:适合处理实时数据流,事件流可以实时反映系统中的变化。
事件流的实现方式
(1) Servlet 编程中的响应对象:HttpServletResponse
HttpServletResponse
是经典的 Servlet 编程中的响应对象,可以用于向客户端实时推送数据。主要适用于简单的事件流场景。
实现方式:
- 使用
HttpServletResponse
来直接写数据到客户端。 - 通常通过长连接保持客户端和服务器之间的连接,以便持续推送事件数据。
示例代码:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@WebServlet("/event-stream")
public class EventStreamServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 设置响应头,告知客户端这是一个事件流response.setContentType("text/event-stream");response.setCharacterEncoding("UTF-8");// 获取输出流PrintWriter out = response.getWriter();// 模拟一个简单的事件流int endIndex = 100;while (true) {endIndex--;if( endIndex <= 0 ){break;}out.println("data: " + System.currentTimeMillis());out.println(); // 事件的分隔符out.flush();try {Thread.sleep(1000); // 每秒推送一次事件} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}
特点:
- 基本实现:简单地使用
HttpServletResponse
输出流来推送数据。 - 客户端与服务器之间通过长连接保持数据传输。
- 没有事件的流控或背压处理,适用于低负载、简单的应用场景。
客户端代码(HTML + JavaScript):
<!DOCTYPE html>
<html>
<head><title>SSE Example</title><script>const eventSource = new EventSource("/sse-stream");eventSource.onmessage = function(event) {console.log("Received event: ", event.data);document.getElementById("output").innerText = event.data;};</script>
</head>
<body><h1>Server Sent Events Example</h1><div id="output"></div>
</body>
</html>
(2) SseEmitter
仅需
spring-boot-starter-web
即可实现基本SSE功能
SSE(Server-Sent Events)是一种基于HTTP的单向通信协议,允许服务器主动推送实时数据到客户端。其核心特点包括轻量级协议、自动重连机制和浏览器原生支持
实现方式:
- 使用
SseEmitter
长连接保持客户端和服务器之间的连接,以便持续推送事件数据。 - 注意事项
-
- 超时设置:SSE连接默认无超时限制,需显式设置SseEmitter超时参数以避免资源泄漏。
-
- 响应格式:确保响应头包含Content-Type: text/event-stream,事件数据需遵循data: \n\n格式。
-
- 连接管理:使用ConcurrentHashMap管理客户端连接,及时清理断开或超时的SseEmitter实例。
-
- 异常处理:捕获IOException并调用completeWithError()释放资源,避免内存泄漏
-
示例代码:
@RestController
public class SseController {// 使用线程安全集合管理连接private static final ConcurrentHashMap<String, SseEmitter> emitters = new ConcurrentHashMap<>();// 建立SSE连接@GetMapping(value = "/sse/connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public SseEmitter connect(@RequestParam String clientId) {// 设置30秒超时(根据业务调整)SseEmitter emitter = new SseEmitter(30_000L);emitters.put(clientId, emitter);// 注册连接清理回调emitter.onCompletion(() -> emitters.remove(clientId));emitter.onTimeout(() -> emitters.remove(clientId));emitter.onError(e -> {log.error("SSE Error: {}", e.getMessage());emitters.remove(clientId);});// 立即发送初始化握手信号try {emitter.send(SseEmitter.event().name("INIT").data("{\"status\": \"CONNECTED\"}"));} catch (IOException e) {emitter.completeWithError(e);}return emitter;}// 消息推送方法(可从其他服务调用)public void pushMessage(String clientId, String message) {SseEmitter emitter = emitters.get(clientId);if (emitter != null) {try {emitter.send(SseEmitter.event().id(UUID.randomUUID().toString()).name("MESSAGE").data(message));} catch (IOException e) {emitter.completeWithError(e);emitters.remove(clientId);}}}
}
特点:
- SseEmitter: 这是一个用于发送事件流的类。每次调用 emitter.send() 时,都会向客户端推送一个新的事件。
- 线程: 在新线程中模拟事件流的生成,每1秒发送一个事件。你可以根据需要调整事件的生成方式。
- complete() 和 completeWithError(): 这两个方法分别用于表示事件流的正常结束和错误结束。
客户端代码(HTML + JavaScript):
// 建立连接
const eventSource = new EventSource('/sse/connect?clientId=123');// 监听消息
eventSource.addEventListener('MESSAGE', (e) => {console.log('Received:', JSON.parse(e.data));
});// 错误处理
eventSource.onerror = (err) => {console.error('SSE Error:', err);eventSource.close(); // 手动关闭连接
};
(3) WebFlux 实现事件流
在使用 Spring WebFlux 构建事件流时,可以通过响应式编程的方式实现高效的事件推送。WebFlux 是 Spring 5 引入的响应式编程模块,主要用于构建异步和非阻塞的应用程序。WebFlux 通过
Mono
和Flux
来表示异步的数据流,可以非常方便地实现事件流推送。
1. WebFlux 实现事件流的核心概念
- Mono: 表示一个单一的异步值,通常用于返回单个对象或空值。
- Flux: 表示多个异步值的流,通常用于返回多个对象。
WebFlux 是基于非阻塞 I/O 的,能够在高并发的环境下进行高效的事件流处理。它允许服务器以流的方式向客户端推送数据,特别适用于实时应用,如实时通知、事件推送等。
2. 实现事件流的步骤
下面是如何通过 WebFlux 实现事件流的一个简单示例。
示例:通过 WebFlux 推送事件流
- 创建 Spring Boot 项目并添加 WebFlux 依赖
首先,确保你有一个 Spring Boot 项目,并且在pom.xml
中包含 WebFlux 依赖:
<dependencies><!-- WebFlux 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><!-- Spring Boot 启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>
</dependencies>
- 创建事件流控制器
在 WebFlux 中,我们可以使用 Flux
来构建一个事件流。Flux
可以通过不同的方式发出多个数据流。在下面的例子中,我们通过每秒钟发出一个新的时间戳来模拟一个事件流。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.time.Duration;@RestController
public class EventStreamController {@GetMapping("/events")public Flux<String> streamEvents() {// 使用 Flux.interval 每秒钟发送一次事件return Flux.interval(Duration.ofSeconds(1)).map(sequence -> "Event at: " + System.currentTimeMillis());}
}
解释:
Flux.interval(Duration.ofSeconds(1))
创建一个每秒产生一个事件的流。.map()
方法用来将每个时间戳转换成字符串,表示事件数据。- 这个流会一直持续下去,直到客户端关闭连接。
- 创建客户端来接收事件流
在客户端,您可以使用 JavaScript 的EventSource
来接收服务器推送的事件。以下是一个简单的 HTML 页面,展示了如何接收并显示服务器推送的事件:
<!DOCTYPE html>
<html>
<head><title>WebFlux Event Stream</title><script>const eventSource = new EventSource("/events");eventSource.onmessage = function(event) {document.getElementById("event-data").innerText = event.data;};</script>
</head>
<body><h1>WebFlux Event Stream</h1><div id="event-data"></div>
</body>
</html>
解释:
EventSource("/events")
会建立一个长连接,接收从/events
路径推送的事件流。- 每次收到事件时,
onmessage
事件处理程序会将事件内容显示在页面上。 - WebFlux 是实现事件流的理想选择,特别是当需要处理高并发、高吞吐量的事件流时。
- 通过
Flux
和Mono
可以简洁地构建异步事件流。 - 客户端可以通过
EventSource
实现与服务器的事件流通信,提供实时的推送体验。
3. 运行和测试
- 启动 Spring Boot 应用。
- 访问
http://localhost:8080/
查看实时事件流。 - 每秒钟,页面会显示当前的时间戳,表示从服务器推送的事件。
4. WebFlux 特点
- 异步和非阻塞: WebFlux 使用响应式编程模型,处理请求时不会阻塞线程,适合高并发场景。
- 低延迟: 通过
Flux
和Mono
,服务器可以高效地处理多个客户端的事件流。 - 高可扩展性: 适合构建大规模的实时应用(如实时数据分析、推送通知、直播系统等)。
- 与传统 Servlet 的区别: WebFlux 与传统的 Servlet API 不同,它支持响应式和非阻塞操作,能够更好地应对高负载和高并发的场景。
实战用法(AI流式问答)
!!!!!更推荐使用WebFlux !!!!
Springboot
以智普AI的免费AI问答接口为例
配置webclient
package com.gt.quality.ai;import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;import java.time.Duration;/*** 万里悲秋常作客,百年多病独登台** @author : makeJava*/
@Component
public class AiLocalConfig {HttpClient httpClient = HttpClient.create().// 设置连接超时时间为60秒option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000).// 设置响应超时时间为60秒responseTimeout(Duration.ofMillis(60000)).doOnConnected(con -> con.addHandlerLast(// 设置读取超时时间为60秒new ReadTimeoutHandler(60)// 设置写入超时时间为60秒).addHandlerLast(new WriteTimeoutHandler(60)));/*** 智普AI对话使用接口的处理器* 设置为 5MB缓冲区** @param builder Builder* @return WebClient*/@Bean(name = "useDialogue")public WebClient useDialogue(WebClient.Builder builder) {return builder.baseUrl("https://open.bigmodel.cn/api/paas/v4/chat/completions")// 设置为 5MB.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(5 * 1024 * 1024)).clientConnector(new ReactorClientHttpConnector(httpClient)).build();}
}
接口使用
/*** 事件流---式调用问答*/@RequestMapping(value = "/zhi_pu_say", method = {RequestMethod.GET, RequestMethod.POST}, produces = MediaType.TEXT_EVENT_STREAM_VALUE)@Operation(summary = "流式问答")public Flux<String> testSseInvoke(@RequestParam(value = "question", defaultValue = "2025年国家GPD第一季度的详细情况?", required = false) String question) {log.info("question:{}", question);return zhiPuAiProxyService.streamInvoke(question);}/*** 事件流---式调用问答*/@RequestMapping(value = "/jsonToSay", method = RequestMethod.POST, produces = MediaType.TEXT_EVENT_STREAM_VALUE)@Operation(summary = "流式问答")public Flux<String> jsonToSay(@RequestBody String question) {return zhiPuAiProxyService.streamInvoke(question);}
业务http的流是调用智普AI
@Overridepublic Flux<String> streamInvoke(String question) {// Create a map to store the request bodyMap<String, Object> body = new HashMap<>();// Set the model to "glm-4-flash"body.put("model", "glm-4-flash");// Create a list to store the questionsList<Map<String, Object>> questionList = getAiRoleAndUserBody(question);// Add the list of questions to the request bodybody.put("messages", questionList);// Set the request_id to a random UUIDbody.put("request_id", UUID.randomUUID().toString());// Set the do_sample to truebody.put("do_sample", true);// Set the temperature to 0.95body.put("temperature", 0.95);// Set the stream to truebody.put("stream", true);// Set the max_tokens to 4095body.put("max_tokens", 4095);// Create a map to store the response formatMap<String, Object> responseFormat = new HashMap<>();// Set the type of the response format to "json_object"responseFormat.put("type", "json_object");// Add the response format to the request bodybody.put("response_format", responseFormat);// function、retrieval、web_search。body.put("type", "web_search");try {HttpHeaders headers = new HttpHeaders();headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);headers.set("Accept", MediaType.TEXT_EVENT_STREAM_VALUE);headers.set("Accept-Encoding", "gzip, deflate, br");headers.set("Connection", "keep-alive");headers.set("Authorization", "Bearer " + ZhiPuAIConstant.ZHI_PU_AI_API_KEY);// 数据库对话分析return webClient.post().headers(httpHeaders -> httpHeaders.putAll(headers)).bodyValue(JSONUtil.toJsonStr(body)).retrieve().bodyToFlux(String.class).map(s -> s.replaceAll("data:", ""));} catch (Throwable e) {log.error(e.getMessage(), e);return Flux.error(new BusinessSelfException("系统走神了,请稍后再试..."));}}/*** 获取ai角色和用户信息* @param question question* @return*/private List<Map<String, Object>> getAiRoleAndUserBody(String question) {List<Map<String, Object>> questionList = new ArrayList<>();// Create a map to store the first questionMap<String, Object> questionMap = new HashMap<>();// Set the role of the first question to "system"questionMap.put("role", "system");// Set the content of the first questionquestionMap.put("content", "你是一个乐于回答各种问题的小助手,你的任务是提供专业、准确、有洞察力的建议。");// Add the first question to the listquestionList.add(questionMap);// Create a map to store the second questionMap<String, Object> questionMap2 = new HashMap<>();// Set the role of the second question to "user"questionMap2.put("role", "user");// Set the content of the second questionquestionMap2.put("content", question);// Add the second question to the listquestionList.add(questionMap2);return questionList;}
测试接口
Over
相关文章:

Springboot使用事件流调用大模型接口
什么是事件流 事件流(Event Stream) 是一种处理和传递事件的方式,通常用于系统中的异步消息传递或实时数据流。在事件驱动架构(Event-Driven Architecture)中,事件流扮演着至关重要的角色。 事件流的概念…...

计算机网络--2
TCP三次握手 TCP连接为什么需要三次握手 1. 由于网络情况复杂,可能会出现丢包现象,如果第二次握手的时候服务器就认为这个端口可用,然后一直开启,但是如果客户端未收到服务器发送的回复,那么就会重新发送请求,服务器就会重新开启一个端口连接,这样就会浪费一个端口。 三…...
【已解决】WORD域相关问题;错误 未找到引用源;复制域出错;交叉引用域到底是个啥
(微软赶紧倒闭 所有交叉引用域,有两个状态:1.锁定。2.手动。可通过编辑->链接查看。 “锁定”状态域的能力: 1. 导出PDF格式稳定(【已解决】WORD导出PDF时,参考文献上标自动被取消/变为正常文本_word…...

尤雨溪宣布:Vue 生态正式引入 AI
在前端开发领域,Vue 框架一直以其易用性和灵活性受到广大开发者的喜爱。 而如今,Vue 生态在人工智能(AI)领域的应用上又迈出了重要的一步。 尤雨溪近日宣布,Vue、Vite 和 Rolldown 的文档网站均已添加了llms.txt文件,这一举措旨在让大型语言模型(LLM)更方便地理解这些…...

蓝桥杯第十六届c组c++题目及个人理解
本篇文章只是部分题目的理解,代码和思路仅供参考,切勿当成正确答案,欢迎各位小伙伴在评论区与博主交流! 题目:2025 题目解析 核心提取 要求的数中至少有1个0、2个2、1个5 代码展示 #include<iostream> #incl…...
【MVCP】基于解纠缠表示学习和跨模态-上下文关联挖掘的多模态情感分析
多处可看出与同专栏下的DCCMCI很像 abstract 多模态情感分析旨在从多模态数据中提取用户表达的情感信息,包括语言、声学和视觉线索。 然而,多模态数据的异质性导致了模态分布的差异,从而影响了模型有效整合多模态互补性和冗余性的能力。此外,现有的方法通常在获得表征后直…...
Go语言--语法基础4--基本数据类型--类型转换
Go 编程语言中 if 条件语句的语法如下: 1 、基本形式 if 布尔表达式 { /* 在布尔表达式为 true 时执行 */ } If 在布尔表达式为 true 时,其后紧跟的语句块执行,如果为 false 则 不执行。 package main import "fmt"…...

硬件工程师笔记——电子器件汇总大全
目录 1、电阻 工作原理 欧姆定律 电阻的物理本质 一、限制电流 二、分压作用 三、消耗电能(将电能转化为热能) 2、压敏电阻 伏安特性 1. 过压保护 2. 电压调节 3. 浪涌吸收 4. 消噪与消火花 5. 高频应用 3、电容 工作原理 (…...

微软推动智能体协同运作:支持 A2A、MCP 协议
今日凌晨,微软宣布 Azure AI Foundry 和 Microsoft Copilot Studio 两大开发平台支持最新 Agent 开发协议 A2A,并与谷歌合作开发扩大该协议,这一举措对智能体赛道意义重大。 现状与变革意义 当前智能体领域类似战国时代,各家技术…...
Qt模块化架构设计教程 -- 轻松上手插件开发
概述 在软件开发领域,随着项目的增长和需求的变化,保持代码的可维护性和扩展性变得尤为重要。一个有效的解决方案是采用模块化架构,尤其是利用插件系统来增强应用的功能性和灵活性。Qt框架提供了一套强大的插件机制,可以帮助开发者轻松实现这种架构。 模块化与插件系统 模…...

Linxu实验五——NFS服务器
一.NFS服务器介绍 NFS服务器(Network File System)是一种基于网络的分布式文件系统协议,允许不同操作系统的主机通过网络共享文件和目录3。其核心作用在于实现跨平台的资源透明访问,例如在Linux和Unix系统之间共享静态数据&#…...
RV1126 ROS2环境交叉编译及部署(基于官方Docker)
RV1126 ROS2环境交叉编译及部署(基于官方Docker) 0 前言1 SDK源码更新1.1 启动Docker容器1.2 更新SDK源码1.3 SDK更新问题2 ROS2编译配置3 Buildroot rootfs编译ROS2的依赖包3.1 编译问题解决4 使用Docker交叉编译ROS24.1 准备Linux(Ubuntu) PC机的依赖环境4.1.1 Ubuntu PC机…...

20242817李臻《Linux⾼级编程实践》第9周
20242817李臻《Linux⾼级编程实践》第9周 一、AI对学习内容的总结 第十章 Linux下的数据库编程 10.1 MySQL数据库简介 MySQL概述:MySQL是一个开源的关系型数据库管理系统,最初由瑞典MySQL AB公司开发,后经SUN公司收购,现属于O…...
查看YOLO版本的三种方法
查看YOLO版本的三种方法: 一、通过命令行直接查询 使用Python交互式查询: from ultralytics import __version__ print(__version__) # 示例输出: 11.0.5二、检查PyTorch环境兼容性 import torch, ultralytics print(f"PyTorch: {torch.__versi…...
双流 JOIN 与维表 JOIN 的区别
Flink 双流 JOIN 与维表 JOIN 的区别 1. 数据关联的实时性与更新机制 维表 JOIN 基于当前快照 关联外部存储(如 MySQL、HBase)的 最新状态,仅反映处理时间的当前数据,历史结果不会随维表更新而修正。无状态回溯 无法关联历史版…...
MySQL OCP和Oracle OCP怎么选?
近期oracle 为庆祝 MySQL 数据库发布 30 周年,Oracle 官方推出限时福利:2025 年 4 月 20 日至 7 月 31 日期间,所有人均可免费报考 MySQL OCP(Oracle Certified Professional)认证考试(具体可查看MySQL OCP…...
汽车为什么需要以太网?带宽?实时?
一、传统总线“堵车”:为什么CAN、LIN扛不住了? 1. 带宽危机 案例:一辆L3级自动驾驶汽车每秒产生约4GB数据(激光雷达摄像头),而CAN FD总线最高仅8Mbps。若用CAN传输,需 500秒才能传完1秒的数据—…...

开源分享:TTS-Web-Vue系列:SSML格式化功能与高级语音合成
🎯 本文是TTS-Web-Vue系列的第十二篇文章,重点介绍项目新增的SSML格式化功能以及SSML在语音合成中的应用。通过自动格式化和实时预览,我们显著提升了SSML编辑体验,让用户能够更精确地控制语音合成的细节,实现更自然、更…...
[人机交互]理解界面对用户的影响
零.重点 – 什么是情感因素 – 富有表现力的界面 – 用户的挫败感 – 拟人化在交互设计中的应用 – 虚拟人物:代理 一.什么是情感方面 情感是指某事物对心理造成的一种状态 二.计算机科学中存在的两个相关的研究领域 2.1情感计算 机器如何能感知其他代理的情感&…...

FAST-LIO笔记
1.FAST-LIO FAST-LIO 是一个计算效率高、鲁棒性强的激光-惯性里程计系统。该系统通过紧耦合的迭代扩展卡尔曼滤波器(IEKF)将激光雷达特征点与IMU数据进行融合,使其在快速运动、噪声较大或环境复杂、存在退化的情况下仍能实现稳定的导航。 1…...

软考中级软件设计师——UML(统一建模语言)篇
UML的词汇表包含3种构造块:事物、关系和图。事物是对模型中最具有代表性的成分的抽象;关系把事物结合在一起;图聚集了相关的事物。 一、事物 UML 事物是模型中的基本元素,分为 结构事物、行为事物、分组事物、注释事物。 1. 结构事物 类(Class&#x…...

TSN网络与DIOS融合:破解煤矿井下电力系统越级跳闸难题
一、引言 1.1 研究背景与意义 在现代煤矿生产中,井下电力系统作为整个煤矿生产的动力核心,其重要性不言而喻。煤矿井下的各类机械设备,如采煤机、刮板输送机、通风机、排水泵等,都依赖稳定的电力供应才能正常运行。电力系统的稳定…...
python 实现文件批量重命名
以下是使用Python实现文件批量重命名的示例代码。该代码可以将指定目录下的文件按照一定规则进行重命名,这里以将文件重命名为带有编号的文件名为例: import osdef batch_rename(directory):if not os.path.isdir(directory):print(...

SierraNet协议分析使用指导[RDMA]| 如何设置 NVMe QP 端口以进行正确解码
在解码RoCEv2数据包(包括TCP RDMA和RoCE RDMA)时,若捕获的跟踪数据无法正确解码,通常需要执行特定的解码步骤。对于RoCE RDMA跟踪数据的处理,分析器主要采用两种方式获取必要信息以实现数据包解码: 首先&am…...
Nodejs核心机制
文章目录 前言 前言 结合 Node.js 的核心机制进行说明: 解释事件循环的各个阶段。 答案 Node.js 事件循环分为 6 个阶段,按顺序执行: Timers:执行 setTimeout 和 setInterval 的回调。 Pending I/O Callbacks:处理系…...
Win全兼容!五五 Excel Word 转 PDF 工具解决多场景转换难题
各位办公小能手们!今天给你们介绍一款超牛的工具——五五Excel Word批量转PDF工具V5.5版。这玩意儿专注搞批量格式转换,能把Excel(.xls/.xlsx)和Word(.doc/.docx)文档唰唰地变成PDF格式。 先说说它的核心功…...
【Bluedroid】HID DEVICE 连接的源码分析
本文分析Android Bluetooth协议栈中HID device设备连接流程的完整实现,从应用层接口到协议栈底层的交互细节。通过关键函数(如connect()、BTA_HdConnect()、HID_DevConnect()等)的代码解析,重点关注btif、bta、HID协议栈三层的协同机制,揭示BTA_HD_CONN_STATE_EVT事件传递…...
【AI大模型】SpringBoot整合Spring AI 核心组件使用详解
目录 一、前言 二、Spring AI介绍 2.1 Spring AI介绍 2.2 Spring AI主要特点 2.3 Spring AI核心组件 2.4 Spring AI应用场景 2.5 Spring AI优势 2.5.1 与 Spring 生态无缝集成 2.5.2 模块化设计 2.5.3 简化 AI 集成 2.5.4 支持云原生和分布式计算 2.5.5 安全性保障…...
Redis的操作以及Spring Cache框架
Redis是一种开源的内存数据结构存储,用作数据库、缓存和消息代理。它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。在Spring应用中,可以使用Spring Cache框架结合Redis来实现高效的缓存机制。本文将详细介绍Redis的基本操作以及…...
C#输出参数:使用、要求与新特性
在C#编程中,输出参数是一种强大的工具,用于从方法体内把数据传出到调用代码。它的行为与引用参数类似,但也有自己的特点。今天我们就来详细了解一下C#中的输出参数。 输出参数的基本要求 修饰符的使用 输出参数必须在声明和调用中都使用修…...