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

【socketioxide和axum集成-实现websocket实时通信-Rust点滴】

socketioxide的axum集成

  • 启动socketio依靠examle里的layer
  • 一. 使用可变State依靠axum里的example
  • 二.提取client,IP
    • 1. 非代理,tcp,socket对方地址
    • 2.代理情况下socket.req_parts.
  • 三. axum的handle中使用emit发送消息.
    • 1. io,存入State解决.
    • 2.把io存入初始设定作为唯一单例
    • 3.http-post外部调用方式
  • 四.演示几个自己用的消息处理
    • 1 .上线通知、null 未签到提醒、mess人员签到通知
    • 2.离线通知
    • 3.web中shell命令的异步输出.
  • 总结

启动socketio依靠examle里的layer

https://github.com/Totodore/socketioxide
原版echo代码

use axum::routing::get;
use serde_json::Value;
use socketioxide::{extract::{AckSender, Bin, Data, SocketRef},SocketIo,
};
use tracing::info;
use tracing_subscriber::FmtSubscriber;fn on_connect(socket: SocketRef, Data(data): Data<Value>) {info!("Socket.IO connected: {:?} {:?}", socket.ns(), socket.id);socket.emit("auth", data).ok();socket.on("message",|socket: SocketRef, Data::<Value>(data), Bin(bin)| {info!("Received event: {:?} {:?}", data, bin);socket.bin(bin).emit("message-back", data).ok();},);socket.on("message-with-ack",|Data::<Value>(data), ack: AckSender, Bin(bin)| {info!("Received event: {:?} {:?}", data, bin);ack.bin(bin).send(data).ok();},);
}#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {tracing::subscriber::set_global_default(FmtSubscriber::default())?;let (layer, io) = SocketIo::new_layer();io.ns("/", on_connect);io.ns("/custom", on_connect);let app = axum::Router::new().route("/", get(|| async { "Hello, World!" })).layer(layer);info!("Starting server");let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();axum::serve(listener, app).await.unwrap();Ok(())
}

通过文档
https://docs.rs/socketioxide/latest/socketioxide/index.html
和一些搜素出来代码,需要

  • 允许跨域
use tower::ServiceBuilder;
use tower_http::{cors::CorsLayer,cors::Any, services::ServeDir,add_extension::AddExtensionLayer };let app = axum::Router::new().route("/", get( list_keys)).route("/postmsg", post( handl_emit)).route("/ioonline", get( list_keys)).layer(     ServiceBuilder::new().layer(CorsLayer::permissive())// Enable CORS policy.layer(layer))

一. 使用可变State依靠axum里的example

all example axum axum github example readme

我要用的:key_vaule_store.rs axum Arc<RWloc>example
使用了,Arc,这个synce机制,有加锁的办法.
主要逻辑代码
声明结构


type SharedState = Arc<RwLock<State>>;#[derive(Default)]
struct State {db: HashMap<String, Bytes>,
}

引用实现初始化

  .layer(ServiceBuilder::new().load_shed().concurrency_limit(1024).timeout(Duration::from_secs(10)).layer(TraceLayer::new_for_http()).layer(AddExtensionLayer::new(SharedState::default())).into_inner(),)

在hangdle里使用

async fn list_keys(Extension(state): Extension<SharedState>) -> String {let db = &state.read().unwrap().db;db.keys().map(|key| key.to_string()).collect::<Vec<String>>().join("\n")
}

在IO在namespace, handler中使用

//on main init io
io.ns("/chat", on_connect);
//
...
fn on_connect(socket: SocketRef, Data(data): Data<Value>,HttpExtension(state): HttpExtension<SharedState>) {info!(ns = socket.ns(), ?socket.id,   "Socket.IO connected");let mut stalock =state.write().unwrap();stalock.db.insert(socket.id.to_string(), format!("{}@{}",clientip,day()));

axum 的handle参数传递是各种组合,据说可以获得客户IP我也没找到特别合适的,下面介绍.

二.提取client,IP

为了了解每个socketio客户的在线状态,需要提取其IP.作为一个身份标识,最后发现ip不能做id,每个socket client有.自己的id.根据id的connect,disconnect,记录到上面的state.db. id做key, ip@time做value.一个IP可以在刷新时,造成,socket.id的相关的state快速变动,而disconect事件,往往有推后到,新id上线. 如果IP做id, 新的socket,会被旧socket的disconnect搞下线

1. 非代理,tcp,socket对方地址

在建立服务时获得引用,依靠HTTPExtension,这是原始tcp套接字的获取,
日常的app:::server

 axum::serve(listener, app).await.unwrap();

获取地址信息的app::server会携带connect_info::启动:

axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await.unwrap();

完整掩饰

use axum::{extract::ConnectInfo,routing::get,Router,
};
use std::net::SocketAddr;let app = Router::new().route("/", get(handler));async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {format!("Hello {addr}")
}let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await.unwrap();

信息来自,socketioxide的作者,他提供了很及时的帮助.
https://github.com/Totodore/socketioxide/issues/101
这种办法可行,随axum主版本更新,好过,第三方的extractor
比如这个,现在很新,但是我没有验证
https://github.com/imbolc/axum-client-ip

2.代理情况下socket.req_parts.

适应docket容器,非HOST模式,和反向代理的复杂情况.
在代理模式下
在handle里的缺省参数,socketRef的函数socket.req_parts().headers.get(IPKEY)提取到请求信息其中的headers,中的,x-forwarded-for,代理补充的remote-ip数据 ,具体名字可以在调试后确定下来.这是一个通用协议

static IPKEY:&str="x-forwarded-for";
//static IPKEY:&str="host";
static UP_ON:&str="update_online";
fn on_connect(socket: SocketRef, Data(data): Data<Value>,HttpExtension(state): HttpExtension<SharedState>) {info!(ns = socket.ns(), ?socket.id,   "Socket.IO connected");let clientip= match socket.req_parts().headers.get(IPKEY){Some(ipaddr)=> ipaddr.to_str().unwrap(),None=> "127.0.0.1"};

三. axum的handle中使用emit发送消息.

在连接建立时,把socketRef.clone()存入,共享State.然后在get,orpost的axum route handle获取并使用.
主要用于通过url发送广播消息, 不同服务器间的消息传递.
flask–> rust,socketio->socketio client.

因为要完成flask的socketio的解耦.目前只想到了这个办法.
上面的方法,可能造成socketRef的过早释放.不适合做正常的用法.
下面是最终有两种方法可用,

1. io,存入State解决.

#[derive(Default)] 
struct State {db: HashMap<String, String>,socket:Option<SocketIo>,}
type SharedState = Arc<RwLock<State>>;io.ns("/", on_connect);io.ns("/chat", on_connect);let mut newstate=  SharedState::default();newstate.write().unwrap().socket=Some(io);let app = axum::Router::new().route("/", get( list_keys)).route("/postmsg", post( handl_emit)).route("/ioonline", get( list_keys)).layer(     ServiceBuilder::new().layer(AddExtensionLayer::new(newstate)).layer(CorsLayer::permissive())// Enable CORS policy.layer(layer));

得到io以后, 在handle使用,注意io.of是设定namespace, 就是在io.ns里,第一个参数.锁定某个空间.

async fn handl_emit(Extension(state): Extension<SharedState>,extract::Json(payload): extract::Json<emit_body>)  {if let  Some(io)= &state.read().unwrap().socket{io.of("/chat").unwrap().emit(&payload.room,&payload.msg).ok();}println!("/r.n /postmsg to room:{},msg:{}",&payload.room,&payload.msg); 
}
async fn list_keys(Extension(state): Extension<SharedState>) -> Json<HashMap<String, String>> {let db = &state.read().unwrap().db;Json(db.clone())
}

2.把io存入初始设定作为唯一单例

在app启动前,初始化 layer,io, 然后,启动app时传入sever,最后在handle中直接使用。

#[derive(  Clone)]
struct OneIo{io:Box<SocketIo> ,layer:Box<layer::SocketIoLayer>,}
fn initIO()->OneIo{let (layer, io) = SocketIo::new_layer();OneIo{io:Box::new(io),layer:Box::new(layer)}
}
lazy_static! {static ref APP_CONFIG:OneIo  = initIO();
}
........
#[tokio::main] 
async fn main() -> Result<(), Box<dyn std::error::Error>> {
(*APP_CONFIG).io.ns("/", on_connect);
let app = axum::Router::new().route("/", get( list_keys)).route("/postmsg", post( handl_emit)).route("/ioonline", get( list_keys)).layer(     ServiceBuilder::new().layer(AddExtensionLayer::new(newstate)).layer(CorsLayer::permissive())// Enable CORS policy.layer( *APP_CONFIG.layer.clone()))// i dont know why layer.clone() ,complier sugest .;.......
//in some handle 
async fn handl_emit(extract::Json(payload): extract::Json<emit_body>)  {// if let  Some(io)= &state.read().unwrap().socket{APP_CONFIG.io.of("/chat").unwrap().emit(&payload.room,&payload.msg).ok();}
}

3.http-post外部调用方式

这样在另一个web服务,flask里调用

requests.post('http://127.0.0.1:3002/postmsg', json={'room':'backmsg','msg':"asdfsdf"}).text

四.演示几个自己用的消息处理

1 .上线通知、null 未签到提醒、mess人员签到通知

static UP_ON:&str="update_online";
fn on_connect(socket: SocketRef, Data(data): Data<Value>,HttpExtension(state): HttpExtension<SharedState>) {info!(ns = socket.ns(), ?socket.id,   "Socket.IO connected");
//得到IPlet clientip= match socket.req_parts().headers.get(IPKEY){Some(ipaddr)=> ipaddr.to_str().unwrap(),None=> "127.0.0.1"};//更新存储 let mut stalock =state.write().unwrap();stalock.db.insert(socket.id.to_string(), format!("{}@{}",clientip,day()));
//上线提醒
socket.broadcast().emit(UP_ON,&make_stamap(&clientip,true)).ok();
// 对null订阅,发送空值提醒。非空以后网页取消对null在订阅let mut map = HashMap::new();map.insert("data", INFONULL);socket.broadcast().emit("null", &map).ok();  //通知没有签到人员socket.on("mess", |socket: SocketRef, Data::<Value>(data)| {//转发mess, 更新人名,从客户端到机关. let mut map = HashMap::new();map.insert("data", &data);socket.broadcast().emit("mess", &map).ok();;});    ....
}

2.离线通知

update_online 上下线更新.
离线的处理

  //位于 io.ns("/chat", on_connect);定义的on_connect 内部,但是像套娃,需要自己在另外一套一模一样的参数签名socket.on_disconnect(|socket: SocketRef, reason: DisconnectReason,HttpExtension(state): HttpExtension<SharedState>| async move {let clientip= match socket.req_parts().headers.get(IPKEY){Some(ipaddr)=> ipaddr.to_str().unwrap(),None=> "127.0.0.1"};state.write().unwrap().db.remove(&socket.id.to_string());if let Some((key, value)) =state.read().unwrap().db.iter().find(|(_, v)| (**v).contains(&clientip)){println!("找到了第一个符合条件的元素: key={}, value={}", key, value);} else {println!("没有找到符合条件的元素");socket.broadcast().emit(UP_ON,&make_stamap(&clientip,false)).ok();}//  println!("Socket {:?} on ns {} disconnected, reason: {:?}","", socket.ns(), reason);});

3.web中shell命令的异步输出.

flask用线程调用了shell命令,获得标准输出,
sh.py 文件:

  
import subprocess
import os 
import threading
callback=print
def run(command):global callbacktry:# 起线程执行ping命令task = threading.Thread(target=sh, args=(command, callback))task.start()except Exception as e:print(e)def disconnect():global callbackcommand = "./sndcpy.sh  %s i"  run(command) 
@app.route('/api/disconnect')
def disconnect():sh.disconnect()return "OK"

flask定义回调函数

@app.route("/api/shellout/<msg>")    
def shellout(msg):# socketio.emit('shellout',msg,namespace='/chat')import requestsres=requests.post('http://127.0.0.1:3002/postmsg', json={'room':'shellout','msg':msg})return res.text
#绑定回调函数    
sh.callback=shellout  
  • 调用回调函数,核心命令request post .
requests.post('http://127.0.0.1:3002/postmsg', json={'room':'backmsg','msg':"asdfsdf"}).text
  • axum handle,调用state中的io,emit
 if let  Some(io)= &state.read().unwrap().socket{io.of("/chat").unwrap().emit(&payload.room,&payload.msg).ok();}println!("/r.n /postmsg to room:{},msg:{}",&payload.room,&payload.msg); 

总结

更新到这里,主要注重 axum的socketio结合.而前期的是flask-socketio实现签到系统状态更新的前端后端的介绍.这里不再重复.
在实现过程中,修改了html中的js代码. 精简了流程。梳理过程发现了一个在线汇总列表的漏洞.就是上面说的从ip为标识,变更为socket id为标识.在离线过程搜索其他在线IP会话。
本次更新性能和灵活度有了提升,目前的二进制socketio不依赖环境, 随地可运行,扫清了未来全面迁移到rust在障碍。并且本单一功能可以作为扩展,起到保护源代码加密项目逻辑的目的。
![(https://i-blog.csdnimg.cn/direct/09e4d5f0d5c94650a71abd12e1c1a7ad.jpeg#pic_center)

下棋再见.

相关文章:

【socketioxide和axum集成-实现websocket实时通信-Rust点滴】

socketioxide的axum集成 启动socketio依靠examle里的layer一. 使用可变State依靠axum里的example二.提取client,IP1. 非代理,tcp,socket对方地址2.代理情况下socket.req_parts. 三. axum的handle中使用emit发送消息.1. io,存入State解决.2.把io存入初始设定作为唯一单例3.http-…...

计算机网络(第8版)第3章--PPP课后习题

【3-09】 一 个PPP 帧的数据部分(用十六进制写出)是7 D 5EFE 277D 5D7D 5D657D 5E。 试问真正的数据是什么(用十六进制写出)? 解答&#xff1a;把由转义符7D开始的2字节序列用下画线标出&#xff1a; 7D 5E FE 27 7D 5D 7D 5D 65 7D 5E 7D 5E应当还原成为7E。 7D5D 应…...

通过Android Studio修改第三方jar包并重新生成jar包

最近接手了来自公司其他同事的一个Unity项目,里面有一个封装的jar包要改动一下,无奈关于这个jar包的原工程文件丢失了,于是自己动手来修改下jar包,并做下记录。 一、导入第三方jar包 1、新建项目EditJarDemo(项目名随便取) 2、新建libs文件夹,把你要修改的third.jar 复制…...

Rabbitmq 业务异常与未手动确认场景及解决方案

消费端消费异常&#xff0c;业务异常 与 未手动确认是不是一个场景&#xff0c;因为执行完业务逻辑&#xff0c;再确认。解决方案就一个&#xff0c;就是重试一定次数&#xff0c;然后加入死信队列。还有就是消费重新放入队列&#xff0c;然后重新投递给其他消费者&#xff0c;…...

3D机器视觉的类型、应用和未来趋势

3D相机正在推动机器视觉市场的增长。很多制造企业开始转向自动化3D料箱拣选&#xff0c;专注于使用3D视觉和人工智能等先进技术来简化操作并减少开支。 预计3D相机将在未来五年内推动全球机器视觉市场&#xff0c;这得益于移动机器人和机器人拣选的强劲增长。到 2028 年&#…...

LabVIEW在反馈控制时如何解决带约束的控制问题

在LabVIEW中&#xff0c;解决带约束的反馈控制问题通常需要使用先进的控制算法或特定的方法来满足约束条件&#xff0c;同时保证控制系统的性能和稳定性。以下是解决这类问题的一些常用方法和步骤&#xff1a; ​ 1. 定义控制问题及约束条件 确定被控对象的动态特性&#xff08…...

PHP 在 2025 年的现状与展望

PHP 在 2025 年依然强劲&#xff0c;继续为超过 77% 使用已知服务器端编程语言的网站提供动力。这并非仅仅依靠遗留代码&#xff0c;像 WordPress、Shopify 和 Laravel 这样的主流平台持续推动 PHP 的发展&#xff0c;使其保持着 актуальность 并不断进化。 为什么…...

QT c++ 自定义按钮类 加载图片 美化按钮

如果你有需要利用图片美化按钮的情况&#xff0c;本文能帮助你。 鼠标左键按下按钮和松开&#xff0c;按钮显示不同的图片。 1.按钮类 //因为此类比较简单&#xff0c;1个头文件搞定&#xff0c;没有cpp文件 #ifndef CUSTOMBUTTON_H #define CUSTOMBUTTON_H #include <Q…...

夯实前端基础之HTML篇

知识点概览 HTML部分 1. DOM和BOM有什么区别&#xff1f; DOM&#xff08;Document Object Model&#xff09; 当网页被加载时&#xff0c;浏览器会创建页面的对象文档模型&#xff0c;HTML DOM 模型被结构化为对象树 用途&#xff1a; 主要用于网页内容的动态修改和交互&…...

pytest 参数介绍

命令行参数描述常见使用案例-v / --verbose显示每个测试用例的详细信息&#xff0c;包括测试名称和状态pytest -v-s / --captureno禁用输出捕获&#xff0c;允许 print() 输出显示pytest -s-q / --quiet安静模式&#xff0c;减少输出&#xff0c;仅显示每个测试的通过/失败结果…...

蓝桥杯训练

1对于一个字母矩阵&#xff0c;我们称矩阵中的一个递增序列是指在矩阵中找到两个字母&#xff0c;它们在同一行&#xff0c;同一列&#xff0c;或者在同一 45 度的斜线上&#xff0c;这两个字母从左向右看、或者从上向下看是递增的。 例如&#xff0c;如下矩阵中 LANN QIAO有…...

maven的简单介绍

目录 1、maven简介2、maven 的主要特点3、maven的下载与安装4、修改配置文件5、私服(拓展) 1、maven简介 Maven 是一个广泛使用的项目管理和构建工具&#xff0c;主要应用于 Java 项目。Maven 由 Apache 软件基金会开发和维护&#xff0c;它提供了一种简洁且一致的方法来构建、…...

超完整Docker学习记录,Docker常用命令详解

前言 关于国内拉取不到docker镜像的问题&#xff0c;可以利用Github Action将需要的镜像转存到阿里云私有仓库&#xff0c;然后再通过阿里云私有仓库去拉取就可以了。 参考项目地址&#xff1a;使用Github Action将国外的Docker镜像转存到阿里云私有仓库 一、Docker简介 Do…...

Kafka优势剖析-消费者组、并行消费

目录 1. 消费者组&#xff08;Consumer Group&#xff09; 1.1 什么是消费者组&#xff1f; 1.2 消费者组的工作原理 1.3 消费者组的优势 2. 并行消费&#xff08;Parallel Consumption&#xff09; 2.1 什么是并行消费&#xff1f; 2.2 并行消费的工作原理 2.3 并行消…...

MATLAB语言的多线程编程

MATLAB语言的多线程编程 引言 随着计算机技术的不断发展&#xff0c;尤其是在大数据和高性能计算领域&#xff0c;多线程编程逐渐成为一种重要的编程范式。MATLAB作为一种广泛应用于科学计算和工程模拟的高级编程语言&#xff0c;其强大的数学计算功能和丰富的工具箱&#xf…...

强化学习入门

RL学习路径 理解DQN原理 理解 标准版的策略梯度算法(Vanilla Policy Gradient) 模仿学习实践 Actor-Critic原理 从大模型机器人到imitation Learning与diffusion policy、ACT(Action Chunking with Transformers)的关系 大模型与机器人 tmp: 强化学习中的优势函数&#…...

Unity 2d描边基于SpriteRender,高性能的描边解决方案

目标 以Unity默认渲染管线为例&#xff0c;打造不需要图片内边距&#xff0c;描边平滑&#xff0c;高性能的描边解决方案 前言 在2d游戏中经常需要给2d对象添加描边&#xff0c;来突出强调2d对象 当你去网上查找2d描边shader&#xff0c;移植到项目里面&#xff0c;大概率会…...

2025第2周 | JavaScript中的Symbol

目录 1. Symbol是个什么东东&#xff1f;1.1 语法 2. 为什么需要Symbol?3. 怎么使用Symbol?3.1 定义对象字面量3.2 新增对象属性3.3 使用 Object.defineProperty方式3.4 遍历 4. 静态方法4.1 Symbol.for(key)4.2 Symbol.keyFor(symbol) 2025&#xff0c;做想做的事&#xff0…...

Unity学习之UGUI进阶

一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 &#xff08;1&#xff09;常用事件接口 &#xff08;2&#xff09;不常用事件接口 3、使用事件监听接口 &#…...

IT面试求职系列主题-Jenkins

想成功求职&#xff0c;必要的IT技能一样不能少&#xff0c;先说说Jenkins的必会知识吧。 1) 什么是Jenkins Jenkins 是一个用 Java 编写的开源持续集成工具。它跟踪版本控制系统&#xff0c;并在发生更改时启动和监视构建系统。 2&#xff09;Maven、Ant和Jenkins有什么区别…...

Allure 集成 pytest

Allure 是一个强大的测试报告工具&#xff0c;与 pytest 集成可以生成详细的测试报告&#xff0c;包括测试步骤、测试数据、截图、错误堆栈等。 1. 安装 Allure 和相关依赖 安装 pytest-allure-adaptor 插件&#xff1a; pip install allure-pytest确保本地已安装 Allure 工具。…...

Redis高频知识点

Redis 目录 1 Redis是AP的还是CP的&#xff1f;2 介绍一下Redis的集群方案&#xff1f;3 什么是Redis的数据分片&#xff1f;4 Redis为什么这么快&#xff1f;5 Redis 的事务机制是怎样的&#xff1f;7 Redis的持久化机制是怎样的&#xff1f;8 Redis 的过期策略是怎么样的&a…...

【电子通识】PWM驱动让有刷直流电机恒流工作

电机的典型驱动方法包括电压驱动、电流驱动以及PWM驱动。本文将介绍采用PWM驱动方式的恒流工作。 首先介绍的是什么是PWM驱动的电机恒流工作&#xff0c;其次是PWM驱动电机恒流工作时电路的工作原理。 PWM驱动 当以恒定的电流驱动电机时&#xff0c;电机会怎样工作呢&#xff1…...

PyMysql 02|(包含项目实战)数据库工具类封装

目录 七、数据库工具类封装 1、封装的目的 2、设计数据库工具类 3、实现类方法 1️⃣获取、关闭连接 2️⃣查询一条记录 3️⃣增删改数据 4️⃣完整封装代码实现 七、数据库工具类封装 1、封装的目的 将常用的数据库操作&#xff0c;封装到一个方法。 后续再操作数据…...

Pixel 6a手机提示无法连接移动网络,打电话失败!

1、开启VoLTE 2、如果没有&#xff0c;下载shizuku和PixelIMS应用。 shizuke Releases RikkaApps/Shizuku GitHub PixellMS Release v1.2.8 kyujin-cho/pixel-volte-patch GitHub 3、安装shizuke启动&#xff0c;开通root可以直接点击下面的启动&#xff0c;如果没有就…...

ubuntu20.04 在线安装postgresql 扩展postgis

基础配置 /etc/apt/sources.list # 添加pg官方基础配置deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main# 添加ubuntu官方依赖&#xff08;防止下载依赖错误&#xff09;deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse de…...

fitz获取pdf内容

1.获取pdf单页&#xff0c;及所有内容 import fitz # PyMuPDF# 打开 PDF 文件 pdf_path r"/data2/ljsang/0106/0725_Self-organization-of-plasticity-and-specialization-in-a-primi_2022_Cell-Syst.pdfπσΣ╕╖σσ║Θ║∩╝Φ╛τ▒│σ¡τ╛π.pdf" d…...

LabVIEW软件Bug的定义与修改

在LabVIEW软件开发过程中&#xff0c;bug&#xff08;程序错误或缺陷&#xff09;指的是程序中导致不符合预期行为的任何问题。Bug可能是由于编码错误、逻辑漏洞、硬件兼容性问题、系统资源限制等因素引起的。它可能会导致程序崩溃、功能无法正常执行或输出结果不符合预期。理解…...

Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开

element文档链接&#xff1a; https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注&#xff1a;Vue3在样式中修改箭头图标无效&#xff0c;可能我设置不对&#xff0c;欢迎各位来交流指导 转变思路&#xff1a;隐藏箭头&…...

HTML 音频(Audio)

HTML 音频(Audio) HTML5 引入了新的音频标签 <audio>,使得在网页上嵌入音频文件变得更加简单。在此之前,播放音频通常需要依赖于第三方插件,如 Flash。但随着 HTML5 的普及,浏览器原生支持音频播放,极大地提升了用户体验和网页性能。 基本用法 要使用 HTML5 的音…...

linux音视频采集技术: v4l2

简介 在 Linux 系统中&#xff0c;视频设备的支持和管理离不开 V4L2&#xff08;Video for Linux 2&#xff09;。作为 Linux 内核的一部分&#xff0c;V4L2 提供了一套统一的接口&#xff0c;允许开发者与视频设备&#xff08;如摄像头、视频采集卡等&#xff09;进行交互。无…...

基于高斯混合模型的数据分析及其延伸应用(具体代码分析)

一、代码分析 &#xff08;一&#xff09;清除工作区和命令行窗口 clear; clc;clear;&#xff1a;该命令用于清除 MATLAB 工作区中的所有变量&#xff0c;确保代码运行环境的清洁&#xff0c;避免之前遗留的变量对当前代码运行产生干扰。例如&#xff0c;如果之前运行的代码中…...

内网基础-防火墙-隧道技术

内网对抗-网络通讯篇&防火墙组策略&入站和出站规则&单层双层&C2正反向上线 关闭第一个防火墙&#xff1a; 第一个上线就走反向或者正向 第二个上线走反向&#xff08;第二个防火墙阻止入站&#xff09; 关闭第二个防火墙&#xff1a; 第一个上线就走反向&a…...

123.【C语言】数据结构之快速排序挖坑法和前后指针法

目录 1.挖坑法 执行流程 代码 运行结果 可读性好的代码 2.前后指针法(双指针法) 执行流程 单趟排序代码 将单趟排序代码改造后 写法1 简洁的写法 3.思考题 1.挖坑法 执行流程 "挖坑法"顾名思义:要有坑位,一开始将关键值放入临时变量key中,在数组中形成…...

【沉默的羔羊心理学】汉尼拔的“移情”游戏:操纵与理解的艺术,精神分析学视角下的角色互动

终极解读《沉默的羔羊》&#xff1a;弗洛伊德精神分析学视角下的深层剖析 关键词 沉默的羔羊弗洛伊德精神分析学角色心理意识与潜意识性别与身份 弗洛伊德精神分析学简介 弗洛伊德的精神分析学是心理学的一个重要分支&#xff0c;主要关注人类行为背后的无意识动机和冲突。…...

Bytebase 3.0.1 - 可配置在 SQL 编辑器执行 DDL/DML

&#x1f680; 新功能 新增环境策略&#xff0c;允许在 SQL 编辑器内直接执行 DDL/DML 语句。 支持为 BigQuery 数据脱敏。 在项目下新增数据访问控制及脱敏管理页面。 在数据库页面&#xff0c;支持回滚到变更历史的某个版本。 &#x1f514; 兼容性变更 禁止工单创建…...

从零手写线性回归模型:PyTorch 实现深度学习入门教程

系列文章目录 01-PyTorch新手必看&#xff1a;张量是什么&#xff1f;5 分钟教你快速创建张量&#xff01; 02-张量运算真简单&#xff01;PyTorch 数值计算操作完全指南 03-Numpy 还是 PyTorch&#xff1f;张量与 Numpy 的神奇转换技巧 04-揭秘数据处理神器&#xff1a;PyTor…...

git使用指南-实践-搭建git私服

一.创建git私服的核心基础 所谓的git私服&#xff0c;其实就是在一个服务器上创建一个个的git仓库&#xff0c;并且这些仓库允许其在一个网络上被其他用户访问。 创建一个最素的git私服&#xff1a;随便找一台linux服务器&#xff0c;这里假设其ip为192.168.0.6&#xff0c;使…...

Node.js JXcore 打包教程

Node.js JXcore 打包教程 介绍 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它允许开发者使用 JavaScript 编写服务器端和网络应用程序。JXcore 是一个流行的 Node.js 发行版,它支持将 Node.js 应用程序打包成单一的可执行文件,使得部署和分发变得更加容易…...

Xshell 8 最新中文免安装绿色版

前言 Xshell8是一个非常受欢迎的远程连接管理软件&#xff0c;它的界面简单易懂&#xff0c;用起来特别方便。能支持好多种连接方式&#xff0c;比如SSH1、SSH2、SFTP、TELNET等等&#xff0c;还有串行协议和其他一些高级功能&#xff0c;基本上你想连什么都能满足。而且&…...

结构型模式4.装饰器模式

结构型模式 适配器模式&#xff08;Adapter Pattern&#xff09;桥接模式&#xff08;Bridge Pattern&#xff09;组合模式&#xff08;Composite Pattern&#xff09;装饰器模式&#xff08;Decorator Pattern&#xff09;外观模式&#xff08;Facade Pattern&#xff09;享元…...

备考蓝桥杯:顺序表详解(静态顺序表,vector用法)

目录 1.顺序表的概念 2.静态顺序表的实现 总代码 3.stl库动态顺序表vector 测试代码 1.顺序表的概念 要理解顺序表&#xff0c;我们要先了解一下什么是线性表 线性表是n个具有相同特征的数据元素的序列 这就是一个线性表 a1是表头 a4是表尾 a2是a3的前驱 a3是a2的后继 空…...

使用uniapp 微信小程序一些好用的插件分享

总结一下自己在开发中遇见的一问题&#xff0c;通过引入组件可以快速的解决 1.zxz-uni-data-select 下拉框选择器(添加下拉框检索&#xff0c;多选功能&#xff0c;多选搜索功能&#xff0c;自定义 下拉框插件&#xff0c;使用这个的原因是因为 uniui uview 组件库下拉框太…...

当遇到 502 错误(Bad Gateway)怎么办

很多安装雷池社区版的时候&#xff0c;配置完成&#xff0c;访问的时候可能会遇到当前问题&#xff0c;如何解决呢&#xff1f; 客户端&#xff0c;浏览器排查 1.刷新页面和清除缓存 首先尝试刷新页面&#xff0c;因为有时候 502 错误可能是由于网络临时波动导致服务器无法连…...

R语言安装教程与常见问题

生物信息基础入门笔记 R语言安装教程与常见问题 今天和大家聊一个非常基础但是很重要的技术问题——如何在不同操作系统上安装R语言&#xff1f;作为生物信息学数据分析的神兵利器&#xff0c;R语言的安装可谓是入门第一步&#xff0c;学术打工人的必备技能。今天分享在Windows…...

windows 下基于docker 部署 guacamole

背景 Apache Guacamole 是一种无客户端或插件的远程桌面网关。它支持多个标准协议&#xff0c;如 VNC、RDP 和 SSH等。记录下部署过程。 步骤 1&#xff0c; 安装docker desktop choco install docker-desktop -y 注&#xff1a; 若windows 11还未安装wsl&#xff0c;则需要…...

JVM实战—OOM的生产案例

1.每秒仅上百请求的系统为何会OOM(RPC超时时间设置过长导致QPS翻几倍) (1)案例背景 在这个案例中&#xff0c;一个每秒仅仅只有100请求的系统却因频繁OOM而崩溃。这个OOM问题会涉及&#xff1a;Tomcat底层工作原理、Tomcat内核参数的设置、服务请求超时时间。 (2)系统发生OOM的…...

oracle闪回恢复数据:(闪回查询,闪回表,闪回库,回收站恢复)

oracle的闪回查询&#xff0c;可以查询提交在表空间的闪回数据&#xff0c;并可以还原所查询的数据&#xff0c;用于恢复短时间内的delele 或者 update 误操作&#xff0c;非常方便&#xff0c;缺点是只能恢复大概几小时内的数据。 文章目录 概要闪回查询恢复数据的主要方法包括…...

STM32 单片机 练习项目 LED灯闪烁LED流水灯蜂鸣器 未完待续

个人学习笔记 文件路径&#xff1a;程序源码\STM32Project-DAP&DAPmini\1-1 接线图 3-1LED闪烁图片 新建项目 新建项目文件 选择F103C8芯片 关闭弹出窗口 拷贝资料 在项目内新建3个文件夹 Start、Library、User Start文件拷贝 从资料中拷贝文件 文件路径&#xff1a;固…...

计算机网络之---数据传输与比特流

数据传输的概念 数据传输是指将数据从一个设备传输到另一个设备的过程。传输过程涉及将高层协议中的数据&#xff08;如包、帧等&#xff09;转化为比特流&#xff0c;在物理介质上传输。 比特流的概念 比特流是数据传输中最基本的单位&#xff0c;它是由0和1组成的连续比特…...