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

【websocket】安装与使用

websocket安装与使用

  • 1. 介绍
  • 2. 安装
  • 3. websocketpp常用接口
  • 4. Websocketpp使用
    • 4.1 服务端
    • 4.2 客户端

1. 介绍

WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的 消息推送机制。

  • 传统的 web 程序都是属于 “一问一答” 的形式,即客户端给服务器发送了一个
    HTTP 请求,服务器给客户端返回一个 HTTP 响应。这种情况下服务器是属于被动的一方,如果客户端不主动发起请求服务器就无法主动给客户端响应
  • 像网页即时聊天这样的程序非常依赖 “消息推送” 的,即需要服务器主动推动消息到客户端。如果只是使用原生的 HTTP 协议,要想实现消息推送一般需要通过 “轮询” 的方式实现, 而轮询的成本比较高并且也不能及时的获取到消息的响应。

基于上述两个问题, 就产生了 WebSocket 协议。WebSocket 更接近于 TCP 这种级别的通信方式,一旦连接建立完成客户端或者服务器都可以主动的向对方发送数据。

原理解析

WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,通过这个附加头信息完成握手过程并升级协议的过程。

在这里插入图片描述

具体协议升级的过程如下:

在这里插入图片描述

报文格式

在这里插入图片描述

报文字段比较多,我们重点关注这几个字段:

  • FIN: WebSocket 传输数据以消息为概念单位,一个消息有可能由一个或多个帧组成,FIN 字段为 1 表示末尾帧。

  • RSV1~3:保留字段,只在扩展时使用,若未启用扩展则应置 1,若收到不全为 0的数据帧,且未协商扩展则立即终止连接。

  • opcode: 标志当前数据帧的类型

    • 0x0: 表示这是个延续帧,当 opcode 为 0 表示本次数据传输采用了数据分片,当前收到的帧为其中一个分片
    • 0x1: 表示这是文本帧
    • 0x2: 表示这是二进制帧
    • 0x3-0x7: 保留,暂未使用
    • 0x8: 表示连接断开
    • 0x9: 表示 ping 帧
    • 0xa: 表示 pong 帧
    • 0xb-0xf: 保留,暂未使用
  • mask:表示 Payload 数据是否被编码,若为 1 则必有 Mask-Key,用于解码
    Payload 数据。仅客户端发送给服务端的消息需要设置。

  • Payload length:数据载荷的长度,单位是字节, 有可能为 7 位、7+16 位、7+64位。假设 Payload length = x

    • x 为 0~126:数据的长度为 x 字节
    • x 为 126:后续 2 个字节代表一个 16 位的无符号整数,该无符号整数的值为数据的长度
    • x 为 127:后续 8 个字节代表一个 64 位的无符号整数(最高位为 0),该无符号整数的值为数据的长度
  • Mask-Key:当 mask 为 1 时存在,长度为 4 字节,解码规则: DECODED[i] =
    ENCODED[i] ^ MASK[i % 4]

  • Payload data: 报文携带的载荷数据

Websocketpp 介绍

WebSocketpp 是一个跨平台的开源(BSD 许可证)头部专用 C++库,它实现了
RFC6455(WebSocket 协议)和 RFC7692(WebSocketCompression Extensions)。它允许将 WebSocket 客户端和服务器功能集成到 C++程序中。在最常见的配置中,全功能网络 I/O 由 Asio 网络库提供。

WebSocketpp 的主要特性包括:

  • 事件驱动的接口
  • 支持 HTTP/HTTPS、WS/WSS、IPv6
  • 灵活的依赖管理 — Boost 库/C++11 标准库
  • 可移植性:Posix/Windows、32/64bit、Intel/ARM
  • 线程安全

WebSocketpp 同时支持 HTTP 和 Websocket 两种网络协议,可以该库作为项目的依赖库用来搭建 HTTP 和 WebSocket 服务器。

总结

websocket是一个应用层的tcp长连接协议。搭建一个websocket服务器其实就是搭建一个tcp服务器,只不过应用层使用websocket协议格式进行数据处理。

与此对比的就是httplib,它是一个短连接,只是让我快速搭建一个Http服务器,让我们重点关注业务处理。假如在一个项目中,不单单是 请求 - 响应 的业务处理,还包含了数据的主动推送,而这种消息数据的主动推送,是Http协议无法实现的。它只能是客户端发起请求,然后服务器收到给一个响应。因此需要搭建一个长连接的服务器,用于服务端主动向客户端推送数据。

选择websocket协议的考虑:因为Http通信支持websocket协议的切换。
websocket通信框架的选择:websocketpp 即支持websocket通信,也支持http通信。

2. 安装

sudo apt-get install libboost-dev libboost-system-dev libwebsocketpp-dev

3. websocketpp常用接口

namespace websocketpp
{typedef lib::weak_ptr<void> connection_hdl;template <typename config>class endpoint : public config::socket_type{typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr;//通信连接类型typedef typename connection_type::ptr connection_ptr;typedef typename connection_type::message_ptr message_ptr;typedef lib::function<void(connection_hdl)> open_handler;typedef lib::function<void(connection_hdl)> close_handler;typedef lib::function<void(connection_hdl)> http_handler;typedef lib::function<void(connection_hdl, message_ptr)> message_handler;/* websocketpp::log::alevel::none 禁止打印所有日志*/void set_access_channels(log::level channels);   /*设置日志打印等级*/void clear_access_channels(log::level channels); /*清除指定等级的日志*//*设置指定事件的回调函数*/void set_open_handler(open_handler h);       /*websocket 握手成功回调处理函数*/void set_close_handler(close_handler h);     /*websocket 连接关闭回调处理函数*/void set_message_handler(message_handler h); /*websocket 消息回调处理函数*/void set_http_handler(http_handler h);       /*http 请求回调处理函数*//*发送数据接口*/void send(connection_hdl hdl, std::string &payload,frame::opcode::value op);void send(connection_hdl hdl, void *payload, size_t len,frame::opcode::value op);/*关闭连接接口*/void close(connection_hdl hdl, close::status::value code,std::string &reason);/*获取 connection_hdl 对应连接的 connection_ptr*///weak_ptr无法对对象直接操作,必须要获得对应的shared_ptr才能对对象进行对应操作connection_ptr get_con_from_hdl(connection_hdl hdl);/*websocketpp 基于 asio 框架实现,init_asio 用于初始化 asio 框架中的 io_service 调度器*/void init_asio();/*设置是否启用地址重用*/void set_reuse_addr(bool value);/*设置 endpoint 的绑定监听端口*/void listen(uint16_t port);/*对 io_service 对象的 run 接口封装,用于启动服务器*/std::size_t run();/*websocketpp 提供的定时器,以毫秒为单位*/timer_ptr set_timer(long duration, timer_handlercallback);};//继承endpointtemplate <typename config>class server : public endpoint<connection<config>, config>{/*初始化并启动服务端监听连接的 accept 事件处理*/void start_accept();};template <typename config>class connection: public config::transport_type::transport_con_type,public config::connection_base{/*发送数据接口*/error_code send(std::string &payload, frame::opcode::value op = frame::opcode::text);/*获取 http 请求头部*/std::string const &get_request_header(std::string const &key)/*获取请求正文*/std::string const &get_request_body();/*设置响应状态码*/void set_status(http::status_code::value code);/*设置 http 响应正文*/void set_body(std::string const &value);/*添加 http 响应头部字段*/void append_header(std::string const &key, std::string const &val);/*获取 http 请求对象*/request_type const &get_request();/*获取 connection_ptr 对应的 connection_hdl */connection_hdl get_handle();};namespace http{namespace parser{class parser{std::string const &get_header(std::string const &key)std::string const &get_body() typedef std::map<std::string, std::string,utility::ci_less> header_list;header_list const &get_headers()}; class request : public parser{/*获取请求方法*/std::string const &get_method()/*获取请求 uri 接口*/std::string const &get_uri()};}};class message_buffer{/*获取 websocket 请求中的 payload 数据类型*/frame::opcode::value get_opcode();/*获取 websocket 中 payload 数据*/std::string const &get_payload();};namespace log{struct alevel{static level const none = 0x0;static level const connect = 0x1;static level const disconnect = 0x2;static level const control = 0x4;static level const frame_header = 0x8;static level const frame_payload = 0x10;static level const message_header = 0x20;static level const message_payload = 0x40;static level const endpoint = 0x80;static level const debug_handshake = 0x100;static level const debug_close = 0x200;static level const devel = 0x400;static level const app = 0x800;static level const http = 0x1000;static level const fail = 0x2000;static level const access_core = 0x00003003;static level const all = 0xffffffff;};}namespace http{namespace status_code{enum value{uninitialized = 0,continue_code = 100,switching_protocols = 101,ok = 200,created = 201,accepted = 202,non_authoritative_information = 203,no_content = 204,reset_content = 205,partial_content = 206,multiple_choices = 300,moved_permanently = 301,found = 302,see_other = 303,not_modified = 304,use_proxy = 305,temporary_redirect = 307,bad_request = 400,unauthorized = 401,payment_required = 402,forbidden = 403,not_found = 404,method_not_allowed = 405,not_acceptable = 406,proxy_authentication_required = 407,request_timeout = 408,conflict = 409,gone = 410,length_required = 411,precondition_failed = 412,request_entity_too_large = 413,request_uri_too_long = 414,unsupported_media_type = 415,request_range_not_satisfiable = 416,expectation_failed = 417,im_a_teapot = 418,upgrade_required = 426,precondition_required = 428,too_many_requests = 429,request_header_fields_too_large = 431,internal_server_error = 500,not_implemented = 501,bad_gateway = 502,service_unavailable = 503,gateway_timeout = 504,http_version_not_supported = 505,not_extended = 510,network_authentication_required = 511};}}namespace frame{namespace opcode{enum value{continuation = 0x0,text = 0x1,binary = 0x2,rsv3 = 0x3,rsv4 = 0x4,rsv5 = 0x5,rsv6 = 0x6,rsv7 = 0x7,close = 0x8,ping = 0x9,pong = 0xA,control_rsvb = 0xB,control_rsvc = 0xC,control_rsvd = 0xD,control_rsve = 0xE,control_rsvf = 0xF,};}}
}

4. Websocketpp使用

4.1 服务端

websocketpp搭建服务器流程:

  1. 定义server类型
  2. 实例化服务器对象
  3. 初始化日志输出 – 关闭日志输出
  4. 初始化asio框架
  5. 设置消息处理/连接握手成功/连接关闭回调函数/连接异常回调函数
  6. 启动地址重用
  7. 设置监听窗口
  8. 开始监听
  9. 启动服务器
#include<iostream>
#include<websocketpp/config/asio_no_tls.hpp>
#include<websocketpp/server.hpp>
#include<sstream>// 1. 定义server类型
typedef websocketpp::server<websocketpp::config::asio> websocketsvr;//websocket握手成功回调函数
void onopen(websocketpp::connection_hdl hdl)
{std::cout<<"websocket长连接建立成功"<<std::endl;
}//websocket 连接关闭回调处理函数
void onclose(websocketpp::connection_hdl hdl)
{std::cout<<"websocket关闭连接"<<std::endl;
}// websocket 连接异常的回调函数
void onfail(websocketsvr *server,websocketpp::connection_hdl hdl)
{std::cout<<"websocket连接异常"<<std::endl;
}//websocket 消息回调处理函数
void onmessage(websocketsvr* server,websocketpp::connection_hdl hdl,websocketsvr::message_ptr msg)
{//1. 获取有效消息载荷数据,进行业务处理std::string body = msg->get_payload();std::cout<<"收到客户端消息: "<<body<<std::endl;//2. 对客户端进行响应//获取通信连接auto conn = server->get_con_from_hdl(hdl);//发送数据conn->send(body + "服务器回复",websocketpp::frame::opcode::text);
}//http 请求回调处理函数
void onhttp(websocketsvr* server,websocketpp::connection_hdl hdl)
{auto conn = server->get_con_from_hdl(hdl);std::stringstream ss;ss << "<!doctype html><html><head>"<< "<title>hello websocket</title><body>"<< "<h1>hello websocketpp</h1>"<< "</body></head></html>";conn->set_body(ss.str());conn->set_status(websocketpp::http::status_code::ok);
}int main()
{// 2. 实例化服务器对象websocketsvr server;// 3. 初始化日志输出 -- 关闭日志输出// all 表示打印全部级别日志// none 表示什么日志都不打印server.set_access_channels(websocketpp::log::alevel::none);// 4. 初始化asio框架server.init_asio();// 5. 设置消息处理/连接握手成功/连接关闭回调函数/连接异常回调函数server.set_open_handler(onopen);server.set_close_handler(onclose);server.set_fail_handler(std::bind(onfail,&server,std::placeholders::_1));server.set_message_handler(std::bind(onmessage,&server,std::placeholders::_1,std::placeholders::_2));server.set_http_handler(std::bind(onhttp,&server,std::placeholders::_1));// 6. 启动地址重用server.set_reuse_addr(true);// 7. 设置监听窗口server.listen(8080);// 8. 开始监听server.start_accept();// 9. 启动服务器server.run();return 0;
}
server:server.ccg++ -o $@ $^ -std=c++17 -lpthread -lboost_system

4.2 客户端

Http 客户端

使用浏览器作为 http 客户端即可, 访问服务器的 8080 端口。

在这里插入图片描述

WS 客户端

HTML<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, 
initial-scale=1.0"><title>Test Websocket</title></head><body><input type="text" id="message"><button id="submit">提交</button><script>// 创建 websocket 实例// ws://124.223.54.148:8080// 类比 http// ws 表示 websocket 协议// 192.168.51.100 表示服务器地址// 8888 表示服务器绑定的端口let websocket = new WebSocket("ws://124.223.54.148:8080");// 处理连接打开的回调函数websocket.onopen = function() {console.log("连接建立");} // 处理收到消息的回调函数// 控制台打印消息websocket.onmessage = function(e) {console.log("收到消息: " + e.data);} // 处理连接异常的回调函数websocket.onerror = function() {console.log("连接异常");} // 处理连接关闭的回调函数websocket.onclose = function() {console.log("连接关闭");} // 实现点击按钮后, 通过 websocket 实例 向服务器发送请求let input = document.querySelector('#message');let button = document.querySelector('#submit');button.onclick = function() {console.log("发送消息: " + input.value);websocket.send(input.value);} </script>
</body>
</html>

在这里插入图片描述

相关文章:

【websocket】安装与使用

websocket安装与使用 1. 介绍2. 安装3. websocketpp常用接口4. Websocketpp使用4.1 服务端4.2 客户端 1. 介绍 WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的 消息推送机制。 传统的 web 程序都是属于 “一问一答” 的形式&#xff0c;即客户端给服务器发送…...

【大模型】LogRAG:基于检索增强生成的半监督日志异常检测

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构D 实验设计D.1 数据集/评估指标D.2 SOTAD.3 实验结果 E 个人总结E.1 优点E.2 不足 A 论文出处 论文题目&#xff1a;LogRAG: Semi-Supervised Log-based Anomaly Detection with Retrieval-Augmented …...

基于SpringBoot实现的大创管理系统设计与实现【源码+文档】

基于SpringBootVue实现的大创管理系统采用前后端分离架构方式&#xff0c;系统设计了管理员、学生、指导老师、院系管理员两种角色&#xff0c;系统实现了用户登录与注册、个人中心、学生管理、指导老师管理、院系管理员管理、优秀项目管理、项目类型管理、项目信息管理、项目申…...

国产高云FPGA实现视频采集转UDP以太网输出,FPGA网络摄像头方案,提供2套Gowin工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目国产高云FPGA基础教程国产高云FPGA相关方案推荐我这里已有的以太网方案 3、设计思路框架工程设计原理框图输入Sensor之-->OV7725摄像头输入Sensor之-->OV5640摄…...

【Linux基础知识系列】第十一篇-Linux系统安全

Linux系统安全是指通过一系列技术和管理措施&#xff0c;保护Linux系统免受各种威胁和攻击&#xff0c;确保系统的完整性、可用性和机密性。随着网络攻击手段的多样化和复杂化&#xff0c;Linux系统安全成为了系统管理员和开发者必须面对的重要课题。本文将从用户认证、权限管理…...

02.管理数据库

管理数据库 1. 创建数据库 mysql> create database db1; Query OK, 1 row affected (0.01 sec)mysql> show databases; -------------------- | Database | -------------------- | db1 | | hellodb | | information_schema | | m…...

Webpack依赖

Webpack到底怎么对我们的项目进行打包捏&#xff1f; 在webpack处理应用程序时&#xff0c;会根据命令或者配置文件找到入口文件 从入口开始&#xff0c;会生成一个依赖关系图&#xff0c;这个依赖关系图会包含应用程序中所需的所有模块&#xff08;.js、css文件、图片、字体…...

自动驾驶科普(百度Apollo)学习笔记

1. 写在前面 在过去的几年里&#xff0c;自动驾驶技术取得飞速发展&#xff0c;人类社会正逐渐走向一个新时代&#xff0c;这个时代中&#xff0c;汽车不仅仅是一个交通工具&#xff0c;更是一个智能的、能够感知环境、做出决策并自主导航的机器伙伴。现在正好也从事这块的工作…...

leetcode_66.加一

题目链接 这道题归类在力扣的数学类中&#xff0c;应该算是一道思维的简单题吧 题是这样的&#xff0c;根据题目我们不难理解&#xff0c;这个题就是在最后一位加 1 然后返回&#xff0c;正如示例所说的那样&#xff0c;当然这很符合我们人的思维&#xff0c;写这种算法题最重要…...

iview-admin静态资源js按需加载配置

iview-admin2.0版本默认加载所有组件的JS&#xff0c;实际情况下&#xff0c;用户访问后台并不会每个页面都浏览。这样就会造成流量及带宽的浪费。可通过修改配置文件vue.config.js来实现按需加载&#xff0c;具体配置如图 image © 著作权归作者所有,转载或内容合作请联系…...

【学习笔记】深入理解Java虚拟机学习笔记——第3章 垃圾收集器与内存分配策略

第3章 垃圾收集器与内存分配策略 3.1 概述 略 3.2 对象已死&#xff1f; “死去”即不可能以任何途径访问到 3.2.1 引用计数算法 每个对象维护一个计数器&#xff0c;引用即加1&#xff0c;引用失效便减1。 3.2.2 可达性分析算法&#xff08;主流&#xff09; 即根据GC…...

抖去推--短视频矩阵系统源码开发

一、开发短视频矩阵系统的源码需要以下步骤&#xff1a; 确定系统需求&#xff1a; 根据客户的具体业务目标&#xff0c;明确系统需实现的核心功能模块&#xff0c;例如用户注册登录、视频内容上传与管理、多维度视频浏览与推荐、用户互动&#xff08;评论、点赞、分享&#xf…...

Windows设置之网络路由

在 Windows 系统中&#xff0c;可以通过配置路由表来实现特定 IP 地址通过无线网卡&#xff08;Wi-Fi&#xff09;连接&#xff0c;而其他流量通过有线以太网连接。 比如&#xff0c;让101.132.45.129 走无线网卡&#xff0c;其他的走有线以太网的具体步骤如下&#xff1a; 通…...

发送文件脚本源码版本

V1 适配win10和 win11 #SingleInstance Force SendMode Input SetWorkingDir %A_ScriptDir%; Global variables global TaskList : [] global CurrentFileConfig : "current_file.ini" global RemainingFilesConfig : "remaining_files.ini" global File…...

Vue部署到Nginx上及问题解决

一、Vue打包 dist文件即打包文件 二、下载Nginx&#xff0c;将dist内容全部复制到Nginx的html下 三、修改Nginx的nginx.conf配置文件&#xff0c;添加try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html; 是 Nginx 配置中的一个重要指令&#xff0c;用于处理…...

MCP(Model Context Protocol)与提示词撰写

随着大模型&#xff08;LLM&#xff09;在复杂任务中的普及&#xff0c;如何让模型高效调用外部工具和数据成为关键挑战。传统函数调用&#xff08;Function Calling&#xff09;依赖开发者手动封装 API&#xff0c;而 MCP&#xff08;Model Context Protocol&#xff09; 通过…...

每日一令:Linux 极简通关指南 - 汇总

专栏列表 &#x1f4bb; 每日一令&#xff1a;Linux 极简通关指南 (25篇) 【基础】每天掌握一个Linux命令 - nsenter&#xff1a;深入容器与命名空间的利器 发布于 2025-06-08 22:27:04【基础】 每天掌握一个Linux命令 - journalctl&#xff1a;系统日志管理的得力助手 发布于…...

项目-- Json-Rpc框架

目录 项目简介环境搭建Ubuntu-22.04 第三方库使用JsonCppMuduo基础类EventLoop类TcpConnection类Buffer类TcpClient类TcpServer类 服务端基本搭建客户端基本搭建 future 项目设计通用模块设计Rpc功能模块设计发现者设计提供者设计服务注册中心设计 Topic功夫模块设计主题管理中…...

因泰立科技H1X激光雷达:因泰立科技为智慧工业注入新动力

在当今工业领域&#xff0c;精准测量与高效作业是推动产业升级的关键因素。因泰立科技推出的H1X三维轮廓扫描激光雷达&#xff0c;凭借其卓越的性能和广泛的应用场景&#xff0c;正成为智慧工业中不可或缺的高科技装备。 产品简介 H1X三维轮廓扫描激光雷达是因泰立科技基于二维…...

day50 随机函数与广播机制

目录 一、随机张量的生成 1.1 torch.randn() 函数 1.2 其他随机函数 1.3 输出维度测试 二、广播机制 2.1 广播机制的规则 2.2 加法的广播机制 二维张量与一维向量相加 三维张量与二维张量相加 二维张量与标量相加 高维张量与低维张量相加 2.3 乘法的广播机制 批量…...

Codeforces Educational 179(ABCDE)

前言 byd这组题纯靠感觉是吧…^_^ b题赛时举了无数个例子都没想明白&#xff0c;然后一直卡到结束&#xff0c;后面题都没看到&#xff0c;结果补题的时候c题d题直接秒了…-_-|| A. Energy Crystals #include <bits/stdc.h> using namespace std;typedef long long …...

基于 actix-web 框架的简单 demo

以下是一个基于 actix-web 框架的简单 demo&#xff0c; 如果你还没有 Rust&#xff0c;我们建议你使用 rustup 来管理你的 Rust 安装。官方 Rust 指南有一个很棒的入门部分。 Actix Web 目前支持的最低 Rust 版本 &#xff08;MSRV&#xff09; 为 1.72。运行 rustup update…...

python:Tkinter 开发邮件客户端,能编写邮件,发送邮件带附件

Python Tkinter 邮件客户端 下面是一个使用 Python Tkinter 开发的简单邮件客户端&#xff0c;支持编写邮件和发送邮件功能&#xff1a; 功能说明 这个邮件客户端包含以下功能&#xff1a; 邮件编写功能&#xff1a; 收件人地址输入抄送地址输入邮件主题输入邮件正文编辑区&…...

CMake基础:gcc/g++编译选项详解

目录 1.编译步骤 2.gcc 与 g 区别 3.gcc 命令的常用选项 3.1.基础编译选项 3.2.优化选项 3.3.调试与分析选项 3.4.链接选项 3.5.语言特性选项&#xff08;C 特化&#xff09; 3.6.安全增强选项 3.7.架构与指令集优化 3.8.其他常用选项 4.常见编译组合示例 5.常用环…...

深入解析Java21核心新特性(虚拟线程,分代 ZGC,记录模式模式匹配增强)

文章目录 前言一、虚拟线程 (Virtual Threads - JEP 444) - 并发的革命1.1 解决的核心问题&#x1f3af;1.2 工作原理与核心机制⚙️1.3 使用详解与最佳实践&#x1f6e0;️1.4 注意事项⚠️1.5 总结 &#x1f4da; 二、分代 ZGC (Generational ZGC - JEP 439) - 低延迟新高度2…...

免费批量去水印工具 - 针对文心一言生成图片

免费批量去水印工具 - 针对文心一言生成图片 工具介绍 这是一款免费的批量去水印工具&#xff0c;专门针对文心一言生成的图片进行处理。通过简单的操作&#xff0c;您可以快速去除图片中的水印。 下载链接 您可以通过以下网盘链接下载工具&#xff1a; 链接: https://pa…...

android 之 MediaExtractor

MediaExtractor 是Android多媒体处理的基础组件&#xff0c;解封装是其核心价值。 一、功能与定位 MediaExtractor 是Android多媒体框架中的媒体解封装工具&#xff0c;主要作用是从媒体文件&#xff08;如MP4、MKV、MP3&#xff09;中分离音视频轨道数据&#xff0c;为后续解…...

行业案例 | ASOS 借助 Azure AI Foundry(国际版)为年轻时尚爱好者打造惊喜体验

英国潮流电商ASOS借力微软Azure OpenAI&#xff0c;打造生成式AI购物新体验。平台整合大语言模型与推荐引擎&#xff0c;通过智能聊天交互帮年轻用户探索穿搭灵感&#xff0c;精准匹配近900个品牌的潮流单品&#xff0c;实现技术升级与个性化需求的双重突破。 使用 Azure Open…...

在WPS中如何启用宏VBA wps.vba.exe下载和安装

首先我们点击导航栏中的【工具】&#xff0c;点击左侧 运行宏&#xff0c;根据提示 点击 立即加载。加载卡在50%时间比较长&#xff0c;耐心等待。 关闭wps重新打开后&#xff0c; word和xls表格都可以使用了。 如果电脑无法联网&#xff0c;需要提前下载 WPS VBA插件 WPS VB…...

12.7Swing控件5 JProgressBar

Swing 进度条&#xff08;JProgressBar&#xff09;是用于可视化展示任务完成进度的组件&#xff0c;通常用于显示长时间运行任务的完成百分比。以下是关于 Swing 进度条的详细介绍&#xff1a; 1. 基本概念与用途 作用&#xff1a;直观展示任务完成进度&#xff0c;避免用户…...