xterm + vue3 + websocket 终端界面
xterm.js 下载插件
// xterm
npm install --save xterm// xterm-addon-fit 使终端适应包含元素
npm install --save xterm-addon-fit// xterm-addon-attach 通过websocket附加到运行中的服务器进程
npm install --save xterm-addon-attach
<template><div :class="props.type ? 'height305' : 'height160'"><el-row><el-col :span="20"><div:class="['xterm', props.type ? 'heightA' : 'heightB']"ref="terminal"v-loading="loading"element-loading-text="拼命连接中"><div class="terminal" id="terminal" ref="terminal"></div></div><div class="textarea"><textarea ref="textarea" v-model="quickCmd" /><div class="bottomOperate flexEnd"><el-button type="primary" @click="sendCmd" :disabled="!quickCmd">发送命令</el-button></div></div></el-col><el-col :span="4"><div :class="['xtermR', props.type ? 'heightA' : 'heightBR']"><el-tabsv-model="tabActiveName"class="demo-tabs"@tab-click="handleClick"><el-tab-pane label="常用命令" name="first"><div v-if="filteredGroups?.length > 0"><div class="marginBottom10"><el-buttontype="primary"size="small"@click="addCmdGroup('addGroup')">新增命令组</el-button><el-button type="primary" size="small" @click="addCmd('add')">新增命令</el-button></div><el-collapsev-loading="loadingR":class="props.type ? 'listBoxA' : 'listBoxB'"><el-collapse-itemv-for="group in filteredGroups":name="group.name":key="group.name"class="custom-collapse-item"><template #title><divclass="flexSpaceBetween"style="width: 100%"@mouseenter="showActions(group.id, true)"@mouseleave="showActions(group.id, false)"><span class="collapse-title">{{ group.name }}</span><span v-show="actionStates[group.id]"><el-buttonlinktype="primary"@click="addCmdGroup('editGroup', group, $event)">编辑</el-button><el-buttonlinktype="primary"@click="del(group.id, 'group', $event)">删除</el-button></span></div></template><template #default><divv-for="item in group.device_command":key="item.id"class="item flexSpaceBetween paddingRight20 marginBottom10"@mouseenter="showActions1(item.id, true)"@mouseleave="showActions1(item.id, false)"><spanclass="usualName"@click="getName(item.name)":title="item.name">{{ item.name }}</span><span v-show="actionStates1[item.id]" class="btns"><el-buttonlinktype="primary"@click="addCmd('edit', item, group.id)">编辑</el-button><el-button link type="primary" @click="del(item.id)">删除</el-button></span></div></template></el-collapse-item></el-collapse></div><div class="flexCenter" v-else>暂无常用命令</div></el-tab-pane><el-tab-pane label="命令记录" name="second"><div:class="props.type ? 'listBoxA' : 'listBoxB'"v-if="globalStore.cmdRecordList?.length > 0"><divv-for="item in globalStore.cmdRecordList":key="item"class="item flexSpaceBetween paddingRight20 marginBottom10"><span class="recordName" @click="getName(item)">{{item}}</span></div></div><div class="flexCenter" v-else>暂无命令记录</div></el-tab-pane></el-tabs></div></el-col></el-row></div><!-- 新增命令组 --><AddTerminalGroup ref="addTerminalGroup" /><!-- 新增命令 --><AddTerminal ref="addTerminal" />
</template>
<script setup>
import "xterm/css/xterm.css";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
import { debounce } from "lodash";
import { ElMessage, ElMessageBox } from "element-plus";
import {ref,reactive,onMounted,onBeforeUnmount,computed,nextTick,getCurrentInstance,
} from "vue";
import { useGlobalStore } from "@/stores/modules/global.js";
import AddTerminalGroup from "./AddTerminalGroup.vue";
import AddTerminal from "./AddTerminal.vue";
import {commandGroupIndex,commandGroupDel,commandDel,
} from "@/api/equipment";
import { WebSocketUrl } from "@/api/request";const props = defineProps({type: {type: String,default: () => {return "";},},currentPathRes: {type: String,default: () => {return "/";},},
});
const globalStore = useGlobalStore();
const { proxy } = getCurrentInstance();
const searchTerm = ref("");
const tabActiveName = ref("first");
const cmdRecordList = ref(globalStore.cmdRecordList); // 命令历史记录
const loadingR = ref(false);
const groups = ref([]);
const quickCmd = ref("");
const actionStates = ref({});
const actionStates1 = ref({});const filteredGroups = computed(() => {if (!searchTerm.value) {return groups.value;}return groups.value.map((group) => {const filteredItems = group.device_command.filter((item) =>item.includes(searchTerm.value));return {...group,device_command: filteredItems,};}).filter((group) => group.device_command.length > 0);
});const showActions = (id, show) => {actionStates.value[id] = show;
};const showActions1 = (id, show) => {actionStates1.value[id] = show;
};const addCmdGroup = (type, row, event) => {if (event) event.stopPropagation();nextTick(() => {proxy.$refs["addTerminalGroup"].showDialog({type,row,});});
};const addCmd = (type, row, group_id) => {nextTick(() => {proxy.$refs["addTerminal"].showDialog({type,groupList: groups.value,row,group_id,});});
};const getName = (val) => {quickCmd.value = val;
};// 发送命令
const sendCmd = () => {if (isWsOpen()) {terminalSocket.value.send(quickCmd.value);// 处理命令历史记录handleCmdRecordList(quickCmd.value);}
};const handleCmdRecordList = (newCmd) => {if (newCmd) {// 对新命令进行trim处理const trimmedCmd = newCmd.trim();// 检查是否有重复值并删除const index = cmdRecordList.value.indexOf(trimmedCmd);if (index !== -1) {cmdRecordList.value.splice(index, 1);}// 将新命令添加到数组最前面cmdRecordList.value.unshift(trimmedCmd);globalStore.setCmdRecordList(cmdRecordList.value);}
};const del = (id, group, event) => {if (event) event.stopPropagation();ElMessageBox.confirm("确认删除吗?", "删除", {confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",}).then(() => {if (group) {commandGroupDel({ id }).then((res) => {if (res.status === 200) {ElMessage.success("删除成功");getTableData();}});} else {commandDel({ id }).then((res) => {if (res.status === 200) {ElMessage.success("删除成功");getTableData();}});}}).catch(() => {});
};//获取表格数据
const getTableData = () => {loadingR.value = true;commandGroupIndex().then((res) => {loadingR.value = false;if (res.status === 200) {groups.value = res.data?.list;}}).catch((error) => {loadingR.value = false;});
};
// 命令列表
getTableData();
//终端信息
const loading = ref(false);
const terminal = ref(null);
const fitAddon = new FitAddon();
let first = ref(true);
let terminalSocket = ref(null);
let term = ref(null);// 初始化WS
const initWS = () => {if (!terminalSocket.value) {createWS();}if (terminalSocket.value && terminalSocket.value.readyState > 1) {terminalSocket.value.close();createWS();}
};// 创建WS
const createWS = () => {loading.value = true;terminalSocket.value = new WebSocket(WebSocketUrl + globalStore.wsUrl);terminalSocket.value.onopen = runRealTerminal; //WebSocket 连接已建立terminalSocket.value.onmessage = onWSReceive; //收到服务器消息terminalSocket.value.onclose = closeRealTerminal; //WebSocket 连接已关闭terminalSocket.value.onerror = errorRealTerminal; //WebSocket 连接出错
};//WebSocket 连接已建立
const runRealTerminal = () => {loading.value = false;let sendData = JSON.stringify({t: "conn",});terminalSocket.value.send(sendData);
};
//WebSocket收到服务器消息
const onWSReceive = (event) => {// 首次接收消息,发送给后端,进行同步适配尺寸if (first.value === true) {first.value = false;resizeRemoteTerminal();if (props.type === "termDia") {autoWriteInfo();}}const blob = new Blob([event.data.toString()], {type: "text/plain",});//将Blob 对象转换成字符串const reader = new FileReader();reader.readAsText(blob, "utf-8");reader.onload = (e) => {// 可以根据返回值判断使用何种颜色或者字体,不过返回值自带了一些字体颜色writeOfColor(reader.result);};
};//WebSocket 连接出错
const errorRealTerminal = (ex) => {let message = ex.message;if (!message) message = "disconnected";term.value.write(`\x1b[31m${message}\x1b[m\r\n`);loading.value = false;
};
//WebSocket 连接已关闭
const closeRealTerminal = () => {loading.value = false;
};// 初始化Terminal
const initTerm = () => {term.value = new Terminal({rendererType: "canvas", //渲染类型// rows: 50, //行数,影响最小高度// cols: 100, // 列数,影响最小宽度convertEol: true, //启用时,光标将设置为下一行的开头// scrollback: 50, //终端中的滚动条回滚量disableStdin: false, //是否应禁用输入。cursorStyle: "underline", //光标样式cursorBlink: true, //光标闪烁theme: {foreground: "#F8F8F8",background: "#2D2E2C",cursor: "help", //设置光标lineHeight: 16,},fontFamily: '"Cascadia Code", Menlo, monospace',});// writeDefaultInfo();// 弹框自动输入term.value.open(terminal.value); //挂载dom窗口term.value.loadAddon(fitAddon); //自适应尺寸term.value.focus();termData(); //Terminal 事件挂载
};const autoWriteInfo = () => {let sendData = "\n" + "cd " + props.currentPathRes + "\n";// term.value.write(`\x1b[37m${sendData}\x1b[m`);// term.value.write("\r\n");if (isWsOpen()) {terminalSocket.value.send(sendData);}
};const writeDefaultInfo = () => {let defaultInfo = ["┌\x1b[1m terminals \x1b[0m─────────────────────────────────────────────────────────────────┐ ","│ │ ","│ \x1b[1;34m 欢迎使用XS SSH \x1b[0m │ ","│ │ ","└────────────────────────────────────────────────────────────────────────────┘ ",];term.value.write(defaultInfo.join("\n\r"));term.value.write("\r\n");// writeOfColor('我是加粗斜体红色的字呀', '1;3;', '31m')
};const writeOfColor = (txt, fontCss = "", bgColor = "") => {// 在Linux脚本中以 \x1B[ 开始,中间前部分是样式+内容,以 \x1B[0m 结尾// 示例 \x1B[1;3;31m 内容 \x1B[0m// fontCss// 0;-4;字体样式(0;正常 1;加粗 2;变细 3;斜体 4;下划线)// bgColor// 30m-37m字体颜色(30m:黑色 31m:红色 32m:绿色 33m:棕色字 34m:蓝色 35m:洋红色/紫色 36m:蓝绿色/浅蓝色 37m:白色)// 40m-47m背景颜色(40m:黑色 41m:红色 42m:绿色 43m:棕色字 44m:蓝色 45m:洋红色/紫色 46m:蓝绿色/浅蓝色 47m:白色)// console.log("writeOfColor", term)term.value.write(`\x1b[37m${fontCss}${bgColor}${txt}\x1b[m`);// term.value.write(`\x1B[${fontCss}${bgColor}${txt}\x1B[0m`);
};// 终端输入触发事件
const termData = () => {fitAddon.fit();// 输入与粘贴的情况,onData不能重复绑定,不然会发送多次term.value.onData((data) => {// console.log(data, "传入服务器");if (isWsOpen()) {terminalSocket.value.send(data);}});// 终端尺寸变化触发term.value.onResize(() => {resizeRemoteTerminal();});
};//尺寸同步 发送给后端,调整后端终端大小,和前端保持一致,不然前端只是范围变大了,命令还是会换行
const resizeRemoteTerminal = () => {const { cols, rows } = term.value;if (isWsOpen()) {terminalSocket.value.send(JSON.stringify({t: "resize",width: rows,height: cols,}));}
};// 是否连接中0 1 2 3 状态
const isWsOpen = () => {// console.log(terminalSocket.value, "terminalSocket.value");const readyState = terminalSocket.value && terminalSocket.value.readyState;return readyState === 1;
};// 适应浏览器尺寸变化
const fitTerm = () => {fitAddon.fit();
};
const onResize = debounce(() => fitTerm(), 500);
const onTerminalResize = () => {window.addEventListener("resize", onResize);
};
const removeResizeListener = () => {window.removeEventListener("resize", onResize);
};//*生命周期函数
onMounted(() => {initWS();initTerm();onTerminalResize();
});onBeforeUnmount(() => {removeResizeListener();let sendData = JSON.stringify({t: "close",});if (isWsOpen()) {terminalSocket.value.send(sendData);terminalSocket.value && terminalSocket.value.close();}
});// 暴露方法
defineExpose({ getTableData });
</script>
<style lang="scss" scoped>
.xterm {position: relative;width: 100%;background: rgb(45, 46, 44);
}.xtermR {position: relative;width: 100%;background: #fff;padding: 10px;position: relative;// overflow: hidden;.listBoxA {overflow-y: auto;height: calc(100vh - 450px);}.listBoxB {overflow-y: auto;height: calc(100vh - 300px);}
}.heightA {height: calc(100vh - 400px);
}
.heightB {height: calc(100vh - 235px);
}
.heightBR {height: calc(100vh - 155px);
}.usualName {width: calc(100% - 80px);display: inline-block;cursor: pointer;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}.btns {width: 80px;
}.textarea {overflow: hidden;position: relative;height: 80px;background: #ffffff;textarea {width: 100%;height: 90px;border: 0 none;outline: none;resize: none;font-size: 15px;overflow-y: auto;padding: 5px;background: #ffffff;}.bottomOperate {position: absolute;right: 10px;bottom: 10px;}
}
.recordName {font-size: 13px;color: #303133;cursor: pointer;margin-bottom: 10px;width: 100%;
}
.flexCenter {font-size: 14px;padding-top: 150px;
}
</style>
此页面兼容了弹框和非弹框页面,做了两种样式处理判断
相关文章:
xterm + vue3 + websocket 终端界面
xterm.js 下载插件 // xterm npm install --save xterm// xterm-addon-fit 使终端适应包含元素 npm install --save xterm-addon-fit// xterm-addon-attach 通过websocket附加到运行中的服务器进程 npm install --save xterm-addon-attach <template><div :…...
解锁 CSS:网页美化与布局的艺术
目录 一、CSS 是什么 二、CSS 的作用 三、CSS 的应用方式(引用方式) 四、选择器:如何挑选要 “打扮” 的元素 五、CSS 属性:丰富多样的 “服装款式” 字体属性: 文本属性:只能控制文字的相关样式。 …...
AWS K8s 部署架构
Amazon Web Services(AWS)提供了一种简化的Kubernetes(K8s)部署架构,使得在云环境中管理和扩展容器化应用变得更加容易。这个架构的核心是AWS EKS(Elastic Kubernetes Service),它是…...
【鸿蒙NEXT】鸿蒙里面类似iOS的Keychain——关键资产(@ohos.security.asset)实现设备唯一标识
前言 在iOS开发中Keychain 是一个非常安全的存储系统,用于保存敏感信息,如密码、证书、密钥等。与 NSUserDefaults 或文件系统不同,Keychain 提供了更高的安全性,因为它对数据进行了加密,并且只有经过授权的应用程序才…...
电子电器架构 --- HUD的工作原理
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...
C# 窗体应用程序嵌套web网页,基于谷歌浏览器内核(含源码)
有一个winform项目,需要借助一个web项目来显示,并且对web做一些操作,web页目是需要用谷歌内核,基于谷歌 Chromium项目的开源Web Browser控件来开发写了一个demo。 安装步骤 第一步:右键项目,点击 管理NuGet程序包 , 输…...
FFmpeg 中 examples 使用教程
FFmpeg 中 examples FFmpeg 的 examples 目录包含了一系列示例程序,旨在展示如何使用 FFmpeg 的不同库和 API。这些示例涵盖了多种功能,包括音视频编解码、格式转换、过滤、网络传输等。以下是一些常见的示例程序及其功能介绍: 音频和视频解码: 示例程序展示了如何打开音视…...
自动化办公-合并多个excel
在日常的办公自动化工作中,尤其是处理大量数据时,合并多个 Excel 表格是一个常见且繁琐的任务。幸运的是,借助 Python 语言中的强大库,我们可以轻松地自动化这个过程。本文将带你了解如何使用 Python 来合并多个 Excel 表格&#…...
Docker搭建MySQL
Docker搭建MySQL 准备工作 先准备配置目录和持久化目录,举个栗子:mkdir -p /opt/module/mysql/{conf,data,log}准备配置文件*.cnf,放到/opt/module/mysql/conf目录下。当然不准备也没事,容器中有个默认配置:/etc/mysql/conf.d/m…...
亚马逊国际站商品爬虫:Python实战指南
在数字化时代,数据的价值不言而喻。对于电商领域而言,获取竞争对手的商品信息、价格、评价等数据,对于市场分析和策略制定至关重要。本文将带你了解如何使用Python编写爬虫,以亚马逊国际站为例,按照关键字搜索并获取商…...
pwntools用法
pwntools 是一个Python库, 用于编写二进制漏洞利用(exploitation)脚本 功能: 远程连接和本地连接: 支持通过TCP/UDP连接远程服务或与本地进程进行交互。Shellcode和ROP链构造: 提供了便捷的工具来生成和利…...
企业云盘怎么选?2024年免费版9款整理
文章介绍了以下9大企业云盘:1.亿方云;2.Worktile;3.百度网盘;4.腾讯云盘;5.阿里云盘;6.金山云盘;7.Dropbox;8.Box。 在企业日常管理中,文件存储和共享一直是个不小的难题…...
Linux之ARM(MX6U)裸机篇----5.仿stm32的LED驱动实验
一,启动文件 .global _start .global _bss_start /* 类似宏定义把__bss_start定义为_bss_start */ _bss_start:.word __bss_start.global _bss_end _bss_end:.word __bss_end_start:#设置处理器进入SVC模式mrs r0, cpsr /* 读取cpsr到r0 */bic r0, r0, …...
Qt从入门到入土(七)-实现炫酷的登录注册界面(下)
前言 Qt从入门到入土(六)-实现炫酷的登录注册界面(上)主要讲了如何使用QSS样式表进行登录注册的界面设计,本篇文章将介绍如何对登录注册界面进行整体控件的布局,界面的切换以及实现登录、记住密码等功能。…...
如何进行年度工作回顾?
发生了什么事? 什么事情进展顺利 ? 什么事情进展不顺利? 如何适应未来? 年度回顾的定义:这是一种战略工具,能帮助人们清晰看到过去一年对业务、职业或个人生活的影响,可用于明确关键事件、找出问…...
spring默认线程池SimpleAsyncTaskExecutor特点为什么要尽量避免使用
在 Spring Boot 中,默认的线程池配置由 TaskExecutionAutoConfiguration 类提供,使用的是 SimpleAsyncTaskExecutor。 SimpleAsyncTaskExecutor特点 每次调用创建新线程: SimpleAsyncTaskExecutor 每次执行任务时都会创建一个新线程…...
每天40分玩转Django:Django表单集
Django表单集 一、知识要点概览表 类别知识点掌握程度要求基础概念FormSet、ModelFormSet深入理解内联表单集InlineFormSet、BaseInlineFormSet熟练应用表单集验证clean方法、验证规则熟练应用自定义配置extra、max_num、can_delete理解应用动态管理JavaScript动态添加/删除表…...
构建混合技术栈的统一监控与日志平台
文章目录 摘要引言构建统一监控与日志平台的核心思路痛点分析解决方案 平台架构设计架构概览 环境准备Java 服务的 Prometheus 指标导出Prometheus 指标采集模块Node.js 日志收集模块3. Logstash 配置4. Grafana 与 Kibana 配置 QA 环节总结未来展望参考资料 摘要 在多技术栈开…...
KOI技术-事件驱动编程(Sping后端)
1 “你日渐平庸,甘于平庸,将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的,那为什么不能是我呢?”——科比布莱恩特 3. “你那么憎恨那些人,和他们斗了那么久,最终却要变得和他们一样,…...
ubuntu 20.04 国内源安装docker
先更新软件包,安装备要apt软件 # 更新软件包索引 sudo apt-get update# 安装需要的软件包以使apt能够通过HTTPS使用仓库 sudo apt-get install ca-certificates curl gnupg lsb-release使用阿里云源 # 添加阿里云官方GPG密钥 curl -fsSL http://mirrors.aliyun.co…...
微信小程序 app.json 配置文件解析与应用
目录 一、什么是 app.json? 二、app.json 文件的基本结构 三、详细解析 app.json 配置项 1. pages:小程序页面路径配置 2. window:窗口样式配置 3. tabBar:底部标签栏配置 4. networkTimeout:网络请求超时配置 …...
C高级:思维导图Day2
目录 总览1 总览2 总览1 压缩与解压缩 打包与解包 软连接与硬链接 ubuntu下关机与重启指令 总览2 结束...
蓝桥杯(Java)(ing)
Java前置知识 输入流: (在Java面向对象编程-CSDN博客里面有提过相关知识------IO流) // 快读快写 static BufferedReader in new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter out new BufferedWriter(new…...
[Pro Git#2] 分支管理 | branch fix_bug , feature | 处理合并冲突
目录 一、Issue模板文件 二、Pull Requests模板文件 分支管理 1. 理解分支 2. 创建与管理分支 1. 切换分支与提交历史 2. 合并分支 3. 删除分支 4. 解决合并冲突 6. 查看分支合并情况 快速创建并切换分支 分支管理策略 分支合并模式 分支管理原则 日常开发环境 …...
Java——集合框架
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1 集合框架概述1.1 内存层面需要针对多个数据进行存储。此时,可以考虑的容器有:1.2 数组存储多个数据方面的特点和弊端1.3 Java集合框架体系…...
Mac 环境 VVenC 编译与编码命令行工具使用教程
VVenC VVenC 是一个开源的高效视频编码器,专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准,主要目的是提供比 HEVC 更高的压缩效率,同时保持或提高视频质量。H.266/VVC…...
WebRTC:实现浏览器与移动应用的实时通信
1.技术简介 (Web Real-Time)是一种开放式实时通信技术,旨在使浏览器和移动应用程序通过简单的API即可实现实时音频、视频和数据传输,而无需安装插件或额外软件。它支持网络应用中的点对点通信,例如视频聊天、语音通话…...
curl+openssl 踩坑笔记
curl编译:点击跳转 踩坑一 * SSL certificate problem: unable to get local issuer certificate * closing connection #0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.se/docs/sslcerts.html …...
【NebulaGraph】变化的多跳查询
【NebulaGraph】变化的多跳查询 1. 需求2. 解决方案2.1 确定查询结构2.2 构建查询语句 3. 追加需求:如果增加每一跳都要指定查询某SPACE下的Tag,或者不查询某个Tag怎么办 1. 需求 存在多跳请求,其中每一跳是从上一跳查询结果为基础的。但是 …...
【C++】九九乘法表编程题详解与多角度对比分析
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目概述题目描述 💯老师的实现方法代码解析优点不足 💯我的实现方法代码解析优点不足 💯实现方法对比💯优化与扩展代码优化…...
node.js卸载并重新安装(超详细图文步骤)
卸载node.js 重新安装nodejs 一、卸载 1、首先进入控制面板卸载程序 2、卸载后 到文件夹中进行进一步的删除 删除上述的几个文件夹 每个人可能不一样,总之是找到自己的nodejs安装路径,下面是我的 ①删除C:UsersAdminAppDataRoaming路径下的npm相关文件…...
redis的集群模式与ELK基础
一、redis的集群模式 1.主从复制 (1)概述 主从模式:这是redis高可用的基础,哨兵和集群都是建立在此基础之上。 主从模式和数据库的主从模式是一样的,主负责写入,然后把写入的数据同步到从服务器ÿ…...
一份关于 Ubuntu 系统下代理配置的故障排查笔记
Ubuntu 网络代理配置与故障排查指南 在使用 Ubuntu 系统时,配置网络代理可以帮助提升网络访问速度或突破网络限制。然而,代理配置过程中可能会遇到各种问题。本文将详细介绍如何在 Ubuntu 下配置网络代理,并提供故障排查的步骤和解决方案。 …...
如何用jmeter工具进行性能测试
前言 今天我们来说说jmeter如何进行性能测试,我们都知道jmeter工具除了可以进行接口功能测试外,还可以进行性能测试。当项目趋于稳定,根据性能需求就可以着手准备性能测试了,今天就说一说jmeter如何进行性能测试,jmet…...
五、Vue 循环语句
文章目录 简介一、基础数组迭代二、对象属性迭代三、整数循环 简介 在 Vue.js 的世界里,当我们需要处理重复性的结构并依据数据动态渲染时,v-for 指令就成了不可或缺的工具,它赋予开发者简洁且强大的能力,轻松应对各种列表渲染场景…...
HMSC联合物种分布模型
联合物种分布模型(Joint Species Distribution Modelling,JSDM)在生态学领域,特别是群落生态学中发展最为迅速,Hmsc是物种群落分层模型的缩写(Hierarchical Modelling of Species Communities),它是一种基于…...
【CPU】risc-v指令集和其他指令集的差别(个人草稿)
第三,在 RISC-V 中对于所有指令,要读写的寄存器的标识符总是在同一位置,意味着在解码指令之前,就可以先开始访问寄存器。在许多其他的 ISA 中,某些指令字段在部分指令中被重用作为源目的地,在其他指令中又被…...
处理元素卡在视野边界,滚动到视野内
效果图如下: 本示例处理场景:点击底部的折叠面板,展开后移动端滚动条位置不变,导致展开内容在视图外。造成面板展开无内容的错觉。 处理核心API: IntersectionObserver 此API可绑定元素并监听元素是否在视野内。若在视野外…...
环,域,体,整区,理想,极大理想,
环: 定义: 加法交换群 乘法半群 分配律 域的定义: 加法交换群 乘法群(去掉0元是交换群) 分配律 Eg:比如整数集合不是域,因为对于乘法来说,去掉0后没有单位元了,但是是环 Eg…...
音视频入门基础:MPEG2-TS专题(22)——FFmpeg源码中,获取TS流的音频信息的实现
音视频入门基础:MPEG2-TS专题系列文章: 音视频入门基础:MPEG2-TS专题(1)——MPEG2-TS官方文档下载 音视频入门基础:MPEG2-TS专题(2)——使用FFmpeg命令生成ts文件 音视频入门基础…...
大模型—Ollama 结构化输出
Ollama 结构化输出 Ollama现在支持结构化输出,使得可以按照由JSON模式定义的特定格式来约束模型的输出。Ollama的Python和JavaScript库已经更新,以支持结构化输出。 结构化输出的用例包括: 从文档中解析数据从图像中提取数据结构化所有语言模型响应比JSON模式更可靠和一致开…...
基于Pytorch和yolov8n手搓安全帽目标检测的全过程
一.背景 还是之前的主题,使用开源软件为公司搭建安全管理平台,从视觉模型识别安全帽开始。主要参考学习了开源项目 https://github.com/jomarkow/Safety-Helmet-Detection,我是从运行、训练、标注倒过来学习的。由于工作原因,抽空…...
数据结构与算法基础(C语言版)
参考资料:https://www.bilibili.com/video/BV1GW421A7qY/ 所有代码均已在Ubuntu 20.04.6 LTS中测试通过 逻辑结构与存储结构 逻辑结构 逻辑结构指的是数据对象中数据元素间的相互关系,分为以下四种: 集合结构 集合结构中的数据元素除了同属于…...
Qt监控系统放大招/历经十几年迭代完善/多屏幕辅屏预览/多层级设备树/网络登录和回放
一、前言说明 近期对视频监控系统做了比较大的更新升级,主要就是三点,第一点就是增加了辅屏预览,这个也是好多个客户需要的功能,海康的iVMS-4200客户端就有这个功能,方便在多个屏幕打开不同的视频进行查看,…...
使用Locust对MySQL进行负载测试
1.安装环境 pip install locust mysql-connector-python 2.设置测试环境 打开MySQL服务 打开Navicat新建查询,输入SQL语句 3.编写locust脚本 load_mysql.py # codingutf-8 from locust import User, TaskSet, task, between import mysql.connector import ran…...
layui多图上传,tp8后端接收处理
环境:layui2.9.21\thinkphp8.1 前端代码: layui.use([upload, layer], function() {const upload layui.upload;const layer layui.layer;const $ layui.$;// 上传图片const uploadInstImage upload.render({elem: #uploadImage,url: /admin/demo/…...
【Rust自学】8.3. String类型 Pt.1:字符串的创建、更新与拼接
8.3.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编…...
Linux(Ubuntu)下ESP-IDF下载与安装完整流程(1)
本文主要看参考官网说明,如下: 快速入门 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 Linux 和 macOS 平台工具链的标准设置 - ESP32-S3 - — ESP-IDF 编程指南 latest 文档 一、安装准备 为了在ESP32-S3中使用ESP-IDF,需要根据操作系统安装一些软件包。可以参考以下安…...
Android性能优化—— 内存优化
Android 系统中,垃圾回收是自动的,比较隐蔽,这就导致一些内存问题表现的并不明显,出现问题后难以定位。常见的内存问题有内存泄漏、内存溢出(Out of Memory)、内存抖动等。 我们做内存优化的主要原因有以下…...
【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算
【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算 一、简介 在MATLAB中计算Sobol二阶效应指数通常涉及到全局敏感性分析(Global Sensitivity Analysis, GSA),其中Sobol方法是一种流行的技术,用于评估模型输入…...