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

[JAVA版本] Websocket获取B站直播弹幕——基于直播开放平台

教程

B站直播间弹幕Websocket获取 — 哔哩哔哩直播开放平台
基于B站直播开放平台开放且未上架时,只能个人使用。

代码实现

1、相关依赖

fastjson2用于解析JSON字符串,可自行替换成别的框架。
hutool-core用于解压zip数据,可自行替换成别的框架。

<dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.40</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>5.8.21</version>
</dependency>

1、新建ProjectRequest.java

用于发送项目start、end、heartbeat请求。
注意:
没有上架的项目,start返回结果没有场次ID,导致end、heartbeat请求不能正常执行。
但是没有关系,start能获得弹幕服务信息就行。

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Nonnull;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;public class ProjectRequest {/*** 项目ID*/private long appId;/*** 身份验证Key*/private String accessKey;/*** 身份验证密钥*/private String accessSecret;public ProjectRequest(long appId, String accessKey, String accessSecret) {this.appId = appId;this.accessKey = accessKey;this.accessSecret = accessSecret;}public final static String START_URL = "https://live-open.biliapi.com/v2/app/start";public final static String END_URL = "https://live-open.biliapi.com/v2/app/end";public final static String HEART_BEAT_URL = "https://live-open.biliapi.com/v2/app/heartbeat";public final static String BATCH_HEART_BEAT_URL = "https://live-open.biliapi.com/v2/app/batchHeartbeat";/*** 接口描述:开启项目第一步,平台会根据入参进行鉴权校验。鉴权通过后,返回长连信息、场次信息和主播信息。开发者拿到长连和心跳信息后,需要参照[长连说明]和[项目心跳],与平台保持健康的* @param code 必填	string	[主播身份码]* param appId 必填	integer(13位长度的数值,注意不要用普通int,会溢出的)	项目ID*/public String start(String code) throws IOException, NoSuchAlgorithmException, InvalidKeyException {Map<String,Object> params = new HashMap<>();params.put("code", code);params.put("app_id", appId);return post(START_URL, params);}/*** 接口描述:项目关闭时需要主动调用此接口,使用对应项目Id及项目开启时返回的game_id作为唯一标识,调用后会同步下线互动道具等内容,项目关闭后才能进行下一场次互动。* param appId 必填	integer(13位长度的数值,注意不要用普通int,会溢出的)	项目ID* param gameId 必填	场次id*/public String end(String gameId) throws IOException, NoSuchAlgorithmException, InvalidKeyException {Map<String,Object> params = new HashMap<>();params.put("game_id", gameId);params.put("app_id", appId);return post(END_URL, params);}/*** 接口描述:项目开启后,需要持续间隔20秒调用一次该接口。平台超过60s未收到项目心跳,会自动关闭当前场次(game_id),同时将道具相关功能下线,以确保下一场次项目正常运行。* 接口地址:/v2/app/heartbeat* 方法:POST* param gameId 必填	场次id*/public String heartbeat(String gameId) throws IOException, NoSuchAlgorithmException, InvalidKeyException {Map<String,Object> params = new HashMap<>();params.put("game_id", gameId);return post(HEART_BEAT_URL, params);}/*** 项目批量心跳* 接口地址:/v2/app/batchHeartbeat* 方法:POST* @param gameIds    必填	[]string	场次id* */public String batchHeartbeat(@Nonnull List<String> gameIds) throws IOException, NoSuchAlgorithmException, InvalidKeyException {Map<String,Object> params = new HashMap<>();params.put("game_ids", JSONArray.toJSONString(gameIds));return post(HEART_BEAT_URL, params);}/*** 自定义post请求* @param url* @param dataMap* @throws IOException* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/private String post(String url, Map<String,Object> dataMap) throws IOException, NoSuchAlgorithmException, InvalidKeyException {String bodyStr = JSONObject.toJSONString(dataMap);HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();con.setRequestMethod("POST");// 设置请求头setHeader(con, bodyStr);// 发送 POST 请求con.setDoOutput(true);try(DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {wr.writeBytes(bodyStr);wr.flush();}// 获取响应结果try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))){// 返回响应结果return  bufferedReader.lines().collect(Collectors.joining("\n"));}}public static String KEY_CONTENT_MD5 = "x-bili-content-md5";public static String KEY_TIMESTAMP = "x-bili-timestamp";public static String KEY_SIGNATURE_NONCE = "x-bili-signature-nonce";/*** 设置请求头* @param con* @param bodyStr 请求体* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/private void setHeader(HttpURLConnection con,String bodyStr) throws NoSuchAlgorithmException, InvalidKeyException {con.setRequestProperty("User-Agent", "Mozilla/5.0");/**----------------------------------------------------------------------------**///必填:接受的返回结果的类型。目前只支持JSON类型,取值:application/json。con.setRequestProperty("Accept", "application/json");//必填:当前请求体(Request Body)的数据类型。目前只支持JSON类型,取值:application/json。con.setRequestProperty("Content-Type", "application/json");//必填:请求体的编码值,根据请求体计算所得。算法说明:将请求体内容当作字符串进行MD5编码。con.setRequestProperty(KEY_CONTENT_MD5, getContentMd5(bodyStr));//必填:unix时间戳,单位是秒。请求时间戳不能超过当前时间10分钟,否则请求会被丢弃。con.setRequestProperty(KEY_TIMESTAMP, String.valueOf(System.currentTimeMillis()/1000));//必填: 版本1.0con.setRequestProperty("x-bili-signature-version", "1.0");//必填:签名唯一随机数。用于防止网络重放攻击,建议您每一次请求都使用不同的随机数con.setRequestProperty(KEY_SIGNATURE_NONCE, UUID.randomUUID().toString());//必填:加密算法con.setRequestProperty("x-bili-signature-method", "HMAC-SHA256");//必填: accesskey idcon.setRequestProperty("x-bili-accesskeyid", accessKey);//必填:请求签名(注意生成的签名是小写的)。关于请求签名的计算方法,请参见签名机制con.setRequestProperty("Authorization", generateSignature(con));}/*** MD5计算*/private String getContentMd5(String content) throws NoSuchAlgorithmException {MessageDigest md5 = MessageDigest.getInstance("MD5");return byte2Hex( md5.digest(content.getBytes(StandardCharsets.UTF_8)) );}/*** 签名 HmacSHA256计算*/public String generateSignature(HttpURLConnection con) throws NoSuchAlgorithmException, InvalidKeyException {StringBuilder s = new StringBuilder();s.append("x-bili-accesskeyid:").append(accessKey).append("\n");s.append("x-bili-content-md5:").append(con.getRequestProperty(KEY_CONTENT_MD5)).append("\n");s.append("x-bili-signature-method:").append("HMAC-SHA256").append("\n");s.append("x-bili-signature-nonce:").append(con.getRequestProperty(KEY_SIGNATURE_NONCE)).append("\n");s.append("x-bili-signature-version:").append("1.0").append("\n");s.append("x-bili-timestamp:").append(con.getRequestProperty(KEY_TIMESTAMP));byte[] headerByte = s.toString().getBytes(StandardCharsets.UTF_8);byte[] secretByte = accessSecret.getBytes(StandardCharsets.UTF_8);Mac mac = Mac.getInstance("HmacSHA256");mac.init(new SecretKeySpec(secretByte, "HmacSHA256"));byte[] bytes = mac.doFinal(headerByte);return byte2Hex(bytes);}/*** 字节数组转16进制字符串* @param bytes* @return*/private static String byte2Hex(byte[] bytes){StringBuffer stringBuffer = new StringBuffer();String temp = null;for (int i=0;i<bytes.length;i++){temp = Integer.toHexString(bytes[i] & 0xFF);if (temp.length()==1){//1得到一位的进行补0操作stringBuffer.append("0");}stringBuffer.append(temp);}return stringBuffer.toString();}
}

3、新建 WebsocketListener.java

用于监听接收到的数据。

import jakarta.websocket.*;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import cn.hutool.core.util.ZipUtil;@ClientEndpoint
public class WebsocketListener {private Session session;private String authBody;public WebsocketListener(String authBody) {this.authBody = authBody;}@OnOpenpublic void onOpen(Session session) throws IOException {System.out.println("已连接服务...");this.session = session;RemoteEndpoint.Async remote = session.getAsyncRemote();//鉴权协议包ByteBuffer authPack = ByteBuffer.wrap(generateAuthPack(authBody));remote.sendBinary(authPack);//每30秒发送心跳包ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();executorService.scheduleAtFixedRate(() -> {try {ByteBuffer heartBeatPack = ByteBuffer.wrap(generateHeartBeatPack());remote.sendBinary(heartBeatPack);} catch (IOException e) {throw new RuntimeException(e);}}, 0, 30, TimeUnit.SECONDS);}@OnMessagepublic void onMessage(ByteBuffer byteBuffer) {//解包unpack(byteBuffer);}@OnClosepublic void onClose(Session session, CloseReason closeReason) {System.out.println("关闭Websocket服务: " + closeReason);}@OnErrorpublic void onError(Session session, Throwable t) {System.out.println("Websocket服务异常: " + t.getMessage());}public interface Opt{short HEARTBEAT = 2;//	客户端发送的心跳包(30秒发送一次)short HEARTBEAT_REPLY = 3;//	服务器收到心跳包的回复 人气值,数据不是JSON,是4字节整数short SEND_SMS_REPLY = 5;//	服务器推送的弹幕消息包short AUTH = 7;//客户端发送的鉴权包(客户端发送的第一个包)short AUTH_REPLY = 8;//服务器收到鉴权包后的回复}public interface Version{short NORMAL = 0;//Body实际发送的数据——普通JSON数据short ZIP = 2; //Body中是经过压缩后的数据,请使用zlib解压,然后按照Proto协议去解析。}/*** 封包* @param jsonStr 数据* @param code 协议包类型* @return* @throws IOException*/public static byte[] pack(String jsonStr, short code) throws IOException {byte[] contentBytes = new byte[0];if(Opt.AUTH == code){contentBytes = jsonStr.getBytes();}try(ByteArrayOutputStream data = new ByteArrayOutputStream();DataOutputStream stream = new DataOutputStream(data)){stream.writeInt(contentBytes.length + 16);//封包总大小stream.writeShort(16);//头部长度 header的长度,固定为16stream.writeShort(Version.NORMAL);stream.writeInt(code);//操作码(封包类型)stream.writeInt(1);//保留字段,可以忽略。if(Opt.AUTH == code){stream.writeBytes(jsonStr);}return data.toByteArray();}}/*** 生成认证包* @return*/public static byte[] generateAuthPack(String jsonStr) throws IOException {return pack(jsonStr, Opt.AUTH);}/*** 生成心跳包* @return*/public static byte[] generateHeartBeatPack() throws IOException {return pack(null, Opt.HEARTBEAT);}/*** 解包* @param byteBuffer* @return*/public static void unpack(ByteBuffer byteBuffer){int packageLen = byteBuffer.getInt();short headLength = byteBuffer.getShort();short protVer = byteBuffer.getShort();int optCode = byteBuffer.getInt();int sequence = byteBuffer.getInt();if(Opt.HEARTBEAT_REPLY == optCode){System.out.println("这是服务器心跳回复");}byte[] contentBytes = new byte[packageLen - headLength];byteBuffer.get(contentBytes);//如果是zip包就进行解包if(Version.ZIP == protVer){unpack(ByteBuffer.wrap(ZipUtil.unZlib(contentBytes)));return;}String content = new String(contentBytes, StandardCharsets.UTF_8);if(Opt.AUTH_REPLY == optCode){//返回{"code":0}表示成功System.out.println("这是鉴权回复:"+content);}//真正的弹幕消息if(Opt.SEND_SMS_REPLY == optCode){System.out.println("真正的弹幕消息:"+content);// todo 自定义处理}//只存在ZIP包解压时才有的情况//如果byteBuffer游标 小于 byteBuffer大小,那就证明还有数据if(byteBuffer.position() < byteBuffer.limit()){unpack(byteBuffer);}}
}

4、使用

public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException, URISyntaxException, DeploymentException {ProjectRequest p = new ProjectRequest(你的应用ID, 你的Access_key, 你的 Access_Secret);//获取弹幕服务信息String result = p.start(你的身份码);JSONObject data = JSONObject.parseObject(result).getJSONObject("data");//个人信息JSONObject anchorInfo = data.getJSONObject("anchor_info");//弹幕服务器信息JSONObject websocketInfo = data.getJSONObject("websocket_info");//弹幕服务器地址JSONArray wssLinks = websocketInfo.getJSONArray("wss_link");//websocket鉴权信息String authBody = websocketInfo.getString("auth_body");//选一个服务器节点String uri = wssLinks.getString(0);WebSocketContainer container = ContainerProvider.getWebSocketContainer();// 连接到WebSocket服务器container.connectToServer(new WebsocketListener(authBody), new URI(uri)); 
}
参数获取
Access_key 和 Access_Secret去B站直播开放平台注册申请个人开发者后就能获得
应用ID成为个人开发者后,在直播开放平台创建应用后,就能获得应用ID
身份码登录B站直播间找到幻星-互动玩法,在里面就能找到身份码

其他版本

【flutter / dart 版本】Websocket获取B站直播间弹幕教程——基于B站直播开发平台

相关文章:

[JAVA版本] Websocket获取B站直播弹幕——基于直播开放平台

教程 B站直播间弹幕Websocket获取 — 哔哩哔哩直播开放平台 基于B站直播开放平台开放且未上架时&#xff0c;只能个人使用。 代码实现 1、相关依赖 fastjson2用于解析JSON字符串&#xff0c;可自行替换成别的框架。 hutool-core用于解压zip数据&#xff0c;可自行替换成别的…...

第一个 Python 程序

三、第一个 Python 程序 好了&#xff0c;说了那么多&#xff0c;现在我们可以来写一下第一个 Python 程序了。 一开始写 Python 程序&#xff0c;个人不太建议用专门的工具来写&#xff0c;不方便熟悉语法&#xff0c;所以这里我先用 Sublime Text 来写&#xff0c;后期可以…...

广告牌安全监测,保障户外广告牌的安全与稳定

随着城市的发展和现代化&#xff0c;广告牌已经成为城市风景的一部分。然而&#xff0c;随之而来的是广告牌安全问题&#xff0c;因为它们暴露在各种天气和环境条件下&#xff0c;一旦掉落&#xff0c;可能对人们的生命和财产造成威胁。广告牌安全监测有效的解决了这一问题&…...

分类预测 | MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单元数据分类预测

分类预测 | MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单元数据分类预测 目录 分类预测 | MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单元数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现KOA-CNN-GRU开普勒算法优化卷积门控循环单…...

进来了解实现官网搜索引擎的三种方法

做网站的目的是对自己的品牌进行推广&#xff0c;让越来越多的人知道自己的产品&#xff0c;但是如果只是做了一个网站放着&#xff0c;然后等着生意找上门来那是不可能的。在当今数字时代&#xff0c;实现官网搜索引擎对于提升用户体验和推动整体性能至关重要。搜索引擎可以帮…...

OpenCV3-Python(7)模板匹配和霍夫检测

模板匹配 膜版匹配不能匹配尺度变换和视角变换的图像 图片中查找和模板相似度最高的图像 计算相似程度最高的位置 res cv.matchTemplate(img , template, method) 该方法返回一个类似灰度图的东西&#xff0c;如果用的相关匹配&#xff0c;那么亮的地方就是可能匹配上的地方 …...

[C++11]花括号{}、initializer_list、auto、decltype

文章目录 1.花括号{ }的扩展2.initializer_list3.auto4.decltype5.容器的增加5.1array[useless]5.2forward_list[useless]5.3unordered_map/unordered_set5.4统一增加 6.知乎文章 1.花括号{ }的扩展 int main() {//C98花括号{ }支持 1.数组 2.结构体struct Point{int _x;int _…...

在Android平板上使用code-server公网远程Ubuntu服务器编程

文章目录 1.ubuntu本地安装code-server2. 安装cpolar内网穿透3. 创建隧道映射本地端口4. 安卓平板测试访问5.固定域名公网地址6.结语 1.ubuntu本地安装code-server 准备一台虚拟机,Ubuntu或者centos都可以&#xff0c;这里以VMwhere ubuntu系统为例 下载code server服务,浏览器…...

宝塔上安装mysql版本比较和区别

在宝塔上安装MySQL时&#xff0c;几个主要版本之间的区别主要在于性能、功能和安全性。 MySQL Community Server&#xff08;社区版本&#xff09;&#xff1a;这是MySQL的开源免费版本&#xff0c;由社区支持&#xff0c;但不提供官方技术支持。这个版本对一般用户来说可能有…...

uniapp微信小程序自定义封装分段器。

uniapp微信小程序自定义封装分段器。 话不多说先上效果 这里我用的是cil框架 vue3 下面贴代码 组价代码&#xff1a; <template><view class"page"><viewv-for"(item, index) in navList":key"index"click"changeNav(ind…...

文心一言 VS 讯飞星火 VS chatgpt (111)-- 算法导论10.2 2题

二、用go语言&#xff0c;用一个单链表 L实现一个栈。要求操作 PUSH和 POP 的运行时间仍为 O(1)。 文心一言&#xff1a; 在 Go 语言中&#xff0c;我们可以用结构体来实现一个单链表&#xff0c;然后再用栈的相关操作。 以下是一个可能的实现方式&#xff1a; package mai…...

小程序中使用echarts的相关配置以及折线图案例(简单易懂)

第一步&#xff1a;引入echarts文件--此文件需要下载&#xff1a; 下载地址&#xff1a;点击此处进行下载echarts文件 点击Download ZIP下载压缩包&#xff0c;注意&#xff1a;e-canvas是我从完整的文件中剥离出来的有用的&#xff0c;不会影响项目。 第二步&#xff1a;把整…...

前端面试回答不好的问题总结

vue生命周期&#xff1a; beforeCreated、created、beforeMount、mount、beforeUptade、uptade、beforeDestroy、destroyed、 Activated、Deactivated 闭包&#xff1a; ECMAScript中&#xff0c;闭包指的是&#xff1a; 从理论角度&#xff1a;所有的函数。因为它们都在创…...

漏洞预警|CVE-2023-38545 Curl 和 libcurl 堆缓冲区溢出漏洞

项目介绍 libcurl是一个跨平台的网络协议库&#xff0c;支持http、https、ftp等多种协议。 项目地址 https://github.com/curl/curl/releases 影响版本 7.69.0-8.3.0 漏洞分析 漏洞成因在于使用SOCKS5代理过程中造成的溢出。当Curl程序使用 SOCKS5代理时&#xff0c;设置…...

【Java 进阶篇】HTML 语义化标签详解

HTML&#xff08;HyperText Markup Language&#xff09;是构建Web页面的标准语言。在HTML中&#xff0c;标签&#xff08;tag&#xff09;是用于定义页面结构和内容的关键元素。在构建网页时&#xff0c;了解如何正确使用HTML标签是非常重要的&#xff0c;因为它们不仅影响页面…...

【思维构造】Element Extermination—CF1375C

Element Extermination—CF1375C 参考文章 思路 若 a 1 < a n a_1<a_n a1​<an​&#xff0c; 初始时 a 2 , . . . , a n − 1 a_2, ..., a_{n-1} a2​,...,an−1​ 这 n − 2 n-2 n−2 个元素中大于 a 1 a_1 a1​ 中的元素都能通过 a 1 a_1 a1​ 而被删除&…...

CSP模拟53联测15 D. 子序列

CSP模拟53联测15 D. 子序列 文章目录 CSP模拟53联测15 D. 子序列题目大意思路code 题目大意 &#xff08;seq / 3s / 512 MiB&#xff09; 给定一个长为 n n n 的仅有小写英文字母构成字符串 S S 1 S 2 ⋯ S n SS_1S_2\cdots S_n SS1​S2​⋯Sn​。我们定义一个字符串是好…...

iceberg-flink 十一:在dlink代码中建表增加catalog地址。

一&#xff1a;catalog 是存储元数据的地方。 二&#xff1a;表中增加catalog地址’ 当我们映射iceberg表的时候&#xff0c;增加了地址&#xff0c;就会成功映射到表 CREATE CATALOG dk_empower WITH(typeiceberg,catalog-typehadoop,warehousehdfs://cluster/iceberg/war…...

多列等高实现

预期效果 多列等高,左右两列高度自适应且一样,分别设置不同背景色效果预览: 分别由6种方法实现 1、使用padding + margin + overflow 实现多列等高效果,具有良好的兼容性; 2、border实现多列等高,左边框宽度为200px,左列浮动,伪元素清除浮动; 3、父元素线性渐变背景色…...

2023 泰山杯 --- Crypto wp

文章目录 题目解题过程part1part2part3 解题代码 题目 from fastecdsa.curve import P521 as Curve from fastecdsa.point import Point from os import urandom from random import getrandbits import uuid from Crypto.PublicKey import DSA from Crypto.Util.number impor…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...