Netty基础—7.Netty实现消息推送服务二

大纲

1.Netty实现HTTP服务器

2.Netty实现WebSocket

3.Netty实现的消息推送系统

(1)基于WebSocket的消息推送系统说明

(2)消息推送系统的PushServer

(3)消息推送系统的连接管理封装

(4)消息推送系统的ping-pong探测

(5)消息推送系统的全连接推送

(6)消息推送系统的HTTP响应和握手

(7)消息推送系统的运营客户端

(8)运营客户端连接PushServer

(9)运营客户端的Handler处理器

(10)运营客户端发送推送消息

(11)浏览器客户端接收推送消息

3.Netty实现的消息推送系统

(1)基于WebSocket的消息推送系统说明

(2)消息推送系统的PushServer

(3)消息推送系统的连接管理封装

(4)消息推送系统的ping-pong探测

(5)消息推送系统的全连接推送

(6)消息推送系统的HTTP响应和握手

(7)消息推送系统的运营客户端

(8)运营客户端连接PushServer

(9)运营客户端的Handler处理器

(10)运营客户端发送推送消息

(11)浏览器客户端接收推送消息

(1)基于WebSocket的消息推送系统说明

首先需要一个运营系统能够基于NettyClient和PushServer建立WebSocket长连接,然后浏览器客户端也要和PushServer建立好WebSocket长连接,接着运营系统会让NettyClient发送Push推送消息给PushServer,最后PushServer再把推送消息发送给浏览器客户端。

首先启动PushServer,然后打开多个网页客户端查看console,接着启动运营客系统在控制台输入消息,这样就可以完成一个完整的消息推送的交互了。

(2)消息推送系统的PushServer

public class NettyPushServer {private static final Logger logger = LogManager.getLogger(NettyPushServer.class);private static final int DEFAULT_PORT = 8998;private int port;public NettyPushServer(int port) {this.port = port;}public void start() throws Exception {logger.info("Netty Push Server is starting.");EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup();EventLoopGroup workerEventLoopGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossEventLoopGroup, workerEventLoopGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {protected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast("logging", new LoggingHandler("DEBUG")).addLast("http-codec", new HttpServerCodec()).addLast("aggregator", new HttpObjectAggregator(65536)).addLast("http-chunked", new ChunkedWriteHandler()).addLast("netty-push-server-handler", new NettyPushServerHandler());}});ChannelFuture channelFuture = serverBootstrap.bind(port).sync();logger.info("Netty Push Server is started, listened[" + port + "].");channelFuture.channel().closeFuture().sync();} finally {bossEventLoopGroup.shutdownGracefully();workerEventLoopGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {NettyPushServer nettyHttpServer = new NettyPushServer(DEFAULT_PORT);nettyHttpServer.start();}
}public class NettyPushServerHandler extends SimpleChannelInboundHandler<Object> {private static final Logger logger = LogManager.getLogger(NettyPushServerHandler.class);@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {logger.info("Client Connection Established: " + ctx.channel());}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {logger.info("Client Disconnected: " + ctx.channel());}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof FullHttpRequest) {handleHttpRequest(ctx, (FullHttpRequest) msg);} else if(msg instanceof WebSocketFrame) {handleWebSocketFrame(ctx, (WebSocketFrame) msg);}}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {ctx.flush();}private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame webSocketFrame) {}private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) {}
}

(3)消息推送系统的连接管理封装

//用来管理连接
public class ChannelManager {private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);private static ConcurrentHashMap<String, ChannelId> channelIds = new ConcurrentHashMap<String, ChannelId>();public static void add(Channel channel) {channelGroup.add(channel);channelIds.put(channel.id().asShortText(), channel.id());}public static void remove(Channel channel) {channelGroup.remove(channel);channelIds.remove(channel.id().asShortText());}public static Channel get(String id) {return channelGroup.find(channelIds.get(id));}public static void pushToAllChannels(TextWebSocketFrame webSocketFrame) {channelGroup.writeAndFlush(webSocketFrame);}
}public class NettyPushServerHandler extends SimpleChannelInboundHandler<Object> {...@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {logger.info("Client Connection Established: " + ctx.channel());ChannelManager.add(ctx.channel());}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {logger.info("Client Disconnected: " + ctx.channel());ChannelManager.remove(ctx.channel());}...
}

(4)消息推送系统的ping-pong探测

public class NettyPushServerHandler extends SimpleChannelInboundHandler<Object> {...private WebSocketServerHandshaker webSocketServerHandshaker;...protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof FullHttpRequest) {handleHttpRequest(ctx, (FullHttpRequest) msg);} else if(msg instanceof WebSocketFrame) {handleWebSocketFrame(ctx, (WebSocketFrame) msg);}}private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame webSocketFrame) {//WebSocket网页客户端发送的是ping消息,它会不停的ping服务端,看看长连接是否存活和有效if (webSocketFrame instanceof PingWebSocketFrame) {logger.info("Receive ping frame from client: " + ctx.channel());WebSocketFrame pongWebSocketFrame = new PongWebSocketFrame(webSocketFrame.content().retain());ctx.channel().write(pongWebSocketFrame);return;}//WebSocket网页客户端发送一个请求过来,请求关闭这个WebSocket连接if (webSocketFrame instanceof CloseWebSocketFrame) {logger.info("Receive close WebSocket request from client: " + ctx.channel());webSocketServerHandshaker.close(ctx.channel(), ((CloseWebSocketFrame) webSocketFrame).retain());return;}...}...
}

(5)消息推送系统的全连接推送

public class NettyPushServerHandler extends SimpleChannelInboundHandler<Object> {...protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof FullHttpRequest) {handleHttpRequest(ctx, (FullHttpRequest) msg);} else if(msg instanceof WebSocketFrame) {handleWebSocketFrame(ctx, (WebSocketFrame) msg);}}private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame webSocketFrame) {//WebSocket网页客户端发送的是ping消息,它会不停的ping服务端,看看长连接是否存活和有效if (webSocketFrame instanceof PingWebSocketFrame) {logger.info("Receive ping frame from client: " + ctx.channel());WebSocketFrame pongWebSocketFrame = new PongWebSocketFrame(webSocketFrame.content().retain());ctx.channel().write(pongWebSocketFrame);return;}//WebSocket网页客户端发送一个请求过来,请求关闭这个WebSocket连接if (webSocketFrame instanceof CloseWebSocketFrame) {logger.info("Receive close WebSocket request from client: " + ctx.channel());webSocketServerHandshaker.close(ctx.channel(), ((CloseWebSocketFrame) webSocketFrame).retain());return;}//WebSocket网页客户端发送请求,但它不是text文本请求if (!(webSocketFrame instanceof TextWebSocketFrame)) {logger.error("Netty Push Server only support text frame, does not support other type frame.");String errorMsg = String.format("%s type frame is not supported.", webSocketFrame.getClass().getName());throw new UnsupportedOperationException(errorMsg);}//WebSocket网页客户端发送一个文本请求过来,是TextFrame类型的String request = ((TextWebSocketFrame)webSocketFrame).text();logger.info("Receive text frame[" + request + "] from client: " + ctx.channel());//构建响应TextWebSocketFrame response = new TextWebSocketFrame(request);//发送给所有连接,全连接推送ChannelManager.pushToAllChannels(response);}...
}

(6)消息推送系统的HTTP响应和握手

public class NettyPushServerHandler extends SimpleChannelInboundHandler<Object> {...private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) {if (!request.decoderResult().isSuccess() || (!"websocket".equals(request.headers().get("Upgrade")))) {DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST);sendHttpResponse(ctx, request, response);return;}logger.info("Receive handshake request from client: " + ctx.channel());//握手建立WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory("ws://localhost:8998/push", null, false);webSocketServerHandshaker = factory.newHandshaker(request);if (webSocketServerHandshaker == null) {WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());} else {webSocketServerHandshaker.handshake(ctx.channel(), request);logger.info("Netty push server handshake with client: " + ctx.channel());}}//HTTP响应private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest request, DefaultFullHttpResponse response) {if (response.status().code() != RESPONSE_CODE_OK) {ByteBuf byteBuf = Unpooled.copiedBuffer(response.status().toString(), CharsetUtil.UTF_8);response.content().writeBytes(byteBuf);logger.info("Http Response is not ok: " + byteBuf.toString(CharsetUtil.UTF_8));byteBuf.release();}ChannelFuture channelFuture = ctx.channel().writeAndFlush(response);if (response.status().code() != RESPONSE_CODE_OK) {channelFuture.addListener(ChannelFutureListener.CLOSE);}}...
}

(7)消息推送系统的运营客户端

public class OperationNettyClient {private static final Logger logger = LogManager.getLogger(OperationNettyClient.class);private static final String WEB_SOCKET_SCHEME = "ws";private static final String WSS_SCHEME = "wss";private static final String LOCAL_HOST = "127.0.0.1";private static final String PUSH_SERVER_URI = System.getProperty("url", "ws://127.0.0.1:8998/push");private static URI uri;private static String scheme;private static String host;private static int port;private static SslContext sslContext;private EventLoopGroup eventLoopGroup;public void start() throws Exception {//...}public static void main(String[] args) throws Exception {uri = new URI(PUSH_SERVER_URI);scheme = getScheme(uri);host = getHost(uri);port = getPort(uri, scheme);checkScheme(scheme);initSslContext(scheme);}private static String getScheme(URI pushServerUri) {return pushServerUri.getScheme() == null ? WEB_SOCKET_SCHEME : pushServerUri.getScheme();}private static String getHost(URI pushServerUri) {return pushServerUri.getHost() == null ? LOCAL_HOST : pushServerUri.getHost();}private static int getPort(URI pushServerUri, String scheme) {int port;if (pushServerUri.getPort() == -1) {if (WEB_SOCKET_SCHEME.equals(scheme)) {port = 80;} else if(WSS_SCHEME.equals(scheme)) {port = 443;} else {port = -1;}} else {port = pushServerUri.getPort();}return port;}//检查scheme是否是ws或wssprivate static void checkScheme(String scheme) {if (!WEB_SOCKET_SCHEME.equals(scheme) && !WSS_SCHEME.equals(scheme)) {logger.error("Only Support ws or wss scheme.");throw new RuntimeException("Only Support ws or wss scheme.");}}//如果WebSocket使用了SSL,也就是wss,那么初始化对应的sslContextprivate static void initSslContext(String scheme) throws Exception {boolean enableSSL = WSS_SCHEME.equals(scheme);if (enableSSL) {sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();} else {sslContext = null;}}
}

(8)运营客户端连接PushServer

public class OperationNettyClient {private static final Logger logger = LogManager.getLogger(OperationNettyClient.class);private static final String WEB_SOCKET_SCHEME = "ws";private static final String WSS_SCHEME = "wss";private static final String LOCAL_HOST = "127.0.0.1";private static final String PUSH_SERVER_URI = System.getProperty("url", "ws://127.0.0.1:8998/push");private static final String INPUT_MESSAGE_QUIT = "quit";private static final String INPUT_MESSAGE_CLOSE = "close";private static final String INPUT_MESSAGE_PING = "ping";private static URI uri;private static String scheme;private static String host;private static int port;private static SslContext sslContext;private EventLoopGroup eventLoopGroup;public Channel start() throws Exception {logger.info("Operation Netty Client is connecting.");eventLoopGroup = new NioEventLoopGroup();WebSocketClientHandshaker webSocketClientHandshaker = WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders());final OperationNettyClientHandler operationNettyClientHandler = new OperationNettyClientHandler(webSocketClientHandshaker);Bootstrap bootstrap = new Bootstrap();bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {protected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline channelPipeline = ch.pipeline();if (sslContext != null) {channelPipeline.addLast(sslContext.newHandler(ch.alloc(), host, port));}channelPipeline.addLast(new HttpClientCodec()).addLast(new HttpObjectAggregator(65536)).addLast(WebSocketClientCompressionHandler.INSTANCE).addLast(operationNettyClientHandler);}});Channel channel = bootstrap.connect(uri.getHost(), port).sync().channel();logger.info("Operation Netty Client connected to push server.");operationNettyClientHandler.channelFuture().sync();return channel;}public void shutdownGracefully() {eventLoopGroup.shutdownGracefully();}public static void main(String[] args) throws Exception {uri = new URI(PUSH_SERVER_URI);scheme = getScheme(uri);host = getHost(uri);port = getPort(uri, scheme);checkScheme(scheme);initSslContext(scheme);OperationNettyClient operationNettyClient = new OperationNettyClient();try {Channel channel = operationNettyClient.start();} finally {operationNettyClient.shutdownGracefully();}}...
}

(9)运营客户端的Handler处理器

public class OperationNettyClientHandler extends SimpleChannelInboundHandler<Object> {private static final Logger logger = LogManager.getLogger(OperationNettyClientHandler.class);private WebSocketClientHandshaker webSocketClientHandshaker;private ChannelFuture channelFuture;public OperationNettyClientHandler(WebSocketClientHandshaker webSocketClientHandshaker) {this.webSocketClientHandshaker = webSocketClientHandshaker;}public ChannelFuture channelFuture() {return channelFuture;}@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {channelFuture = ctx.newPromise();}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {webSocketClientHandshaker.handshake(ctx.channel());logger.info("Operation Netty Client send WebSocket handshake request.");}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {logger.info("netty client disconnected.");}protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {Channel channel = ctx.channel();if (!webSocketClientHandshaker.isHandshakeComplete()) {try {webSocketClientHandshaker.finishHandshake(channel, (FullHttpResponse) msg);logger.info("Netty Client connected.");((ChannelPromise)channelFuture).setSuccess();} catch(WebSocketHandshakeException e) {logger.error("WebSocket handshake failed.", e);((ChannelPromise)channelFuture).setFailure(e);}return;}if (msg instanceof FullHttpResponse) {  FullHttpResponse response = (FullHttpResponse) msg;throw new IllegalStateException("Not Supported HTTP Response.");}WebSocketFrame webSocketFrame = (WebSocketFrame) msg;if (webSocketFrame instanceof TextWebSocketFrame) {TextWebSocketFrame textWebSocketFrame = (TextWebSocketFrame) webSocketFrame;logger.info("Receives text frame: " + textWebSocketFrame.text());} else if(webSocketFrame instanceof PongWebSocketFrame) {logger.info("Receives pong frame: " + webSocketFrame);} else if(webSocketFrame instanceof CloseWebSocketFrame) {logger.info("Receives close WebSocket frame, Netty Client is closing.");channel.close();}}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {logger.error("Operation Netty client handler exception caught.", cause);if (!channelFuture.isDone()) {((ChannelPromise)channelFuture).setFailure(cause);}ctx.close();}
}

(10)运营客户端发送推送消息

public class OperationNettyClient {...public void waitInputMessage(Channel channel) throws Exception {BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));while(true) {logger.info("Wait for input message.");String message = bufferedReader.readLine();if (INPUT_MESSAGE_QUIT.equals(message)) {break;} else if(INPUT_MESSAGE_CLOSE.equals(message)) {channel.writeAndFlush(new CloseWebSocketFrame());channel.closeFuture().sync();break;} else if(INPUT_MESSAGE_PING.equals(message)) {WebSocketFrame webSocketFrame = new PingWebSocketFrame(Unpooled.wrappedBuffer(new byte[] {8, 1, 8, 1}));channel.writeAndFlush(webSocketFrame);} else {WebSocketFrame webSocketFrame = new TextWebSocketFrame(message);channel.writeAndFlush(webSocketFrame);}}}public static void main(String[] args) throws Exception {uri = new URI(PUSH_SERVER_URI);scheme = getScheme(uri);host = getHost(uri);port = getPort(uri, scheme);checkScheme(scheme);initSslContext(scheme);OperationNettyClient operationNettyClient = new OperationNettyClient();try {Channel channel = operationNettyClient.start();//运营客户端发送消息入口operationNettyClient.waitInputMessage(channel);} finally {operationNettyClient.shutdownGracefully();}}...
}

(11)浏览器客户端接收推送消息

<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><title>websocket网页</title></head><body onload="connectServer();"><script type="text/javascript">var websocket;function connectServer() {if ("WebSocket" in window) {console.log("your browser supports websocket!");websocket = new WebSocket("ws://localhost:8998/push");websocket.onopen = function() {console.log("established connection with push server.");}websocket.onmessage = function(ev) {var response = ev.data;console.log("receives push message from netty server: " + response);}}}</script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/898150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能助力家庭机器人:从清洁到陪伴的智能转型

引言&#xff1a;家庭机器人进入智能时代 过去&#xff0c;家庭机器人只是简单的“工具”&#xff0c;主要用于扫地、拖地、擦窗等单一任务。然而&#xff0c;随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;家庭机器人正经历从“机械助手”向“智能管家”甚…

ssh转发笔记

工作中又学到了&#xff0c;大脑转不过来 现有主机A&#xff0c;主机B&#xff0c;主机C A能访问B&#xff0c;B能访问C&#xff0c;A不能访问C C上80端口有个服务&#xff0c;现在A想访问这个服务&#xff0c;领导让用ssh转发&#xff0c;研究半天没找到理想的语句&#xf…

清晰易懂的Miniconda安装教程

小白也能看懂的 Miniconda 安装教程 Miniconda 是一个轻量级的 Python 环境管理工具&#xff0c;适合初学者快速搭建 Python 开发环境。本教程将手把手教你如何在 Windows 系统上安装 Miniconda&#xff0c;并配置基础环境&#xff0c;确保你能够顺利使用 Python 进行开发。即…

Flume详解——介绍、部署与使用

1. Flume 简介 Apache Flume 是一个专门用于高效地 收集、聚合、传输 大量日志数据的 分布式、可靠 的系统。它特别擅长将数据从各种数据源&#xff08;如日志文件、消息队列等&#xff09;传输到 HDFS、HBase、Kafka 等大数据存储系统。 特点&#xff1a; 可扩展&#xff1…

破解企业内部盗版软件管理难题的技术方案

引言&#xff1a;盗版软件——企业数字化转型的“隐形地雷” 据BSA《全球软件调查报告》显示&#xff0c;37%的企业存在员工私自安装盗版软件的行为&#xff0c;由此引发的法律诉讼、数据泄露及罚款风险年均增长28%。LMT基于“预防-检测-治理”三位一体技术框架&#xff0c;为…

Spring源码解析

第一讲 容器接口 BeanFactory和ApplicationContext接口的具体继承关系&#xff1a; ApplicationContext 间接继承了BeanFactory BeanFactory是父接口ApplicationContext是子接口&#xff0c;里面一些功能调用了BeanFactory BeanFactory的功能 表面上只有 getBean&#xff0…

Django Rest Framework 创建纯净版Django项目部署DRF

描述创建纯净版的Django项目和 Django Rest Framework 环境的部署 一、创建Django项目 1. 环境说明 操作系统 Windows11python版本 3.9.13Django版本 V4.2.202. 操作步骤(在Pycharm中操作) 创建Python项目drfStudy、虚拟环境 ​虚拟环境中安装 jdangopip install django==4.…

图解AUTOSAR_CP_NetworkManagementInterface

AUTOSAR 网络管理接口(Nm)详解 AUTOSAR 网络管理接口规范与实现指南 目录 1. 概述 1.1. 网络管理接口的作用1.2. 网络管理接口的特点 2. 网络管理接口架构 2.1. 架构概览2.2. 模块交互关系 3. 网络管理状态机 3.1. 状态定义3.2. 状态转换 4. 协调算法 4.1. 协调关闭流程4.2. 同…

java学习总结(八):Spring boot

一、SpringBoot简介 传统Spring开发缺点&#xff1a; 1、导入依赖繁琐 2、项目配置繁琐 Spring Boot是全新框架(更像是一个工具&#xff0c; 脚手架)&#xff0c;是Spring提供的一个子项目&#xff0c; 用于快速构建Spring应用程序。 随着Spring 3.0的发布&#xff0c;Spring 团…

vue-router实现

实现一个简化版的 vue-router 可以帮助我们更好地理解 Vue 路由是如何工作的。Vue Router 主要的功能是基于浏览器的 URL 来管理组件的显示&#xff0c;能够根据 URL 变化切换不同的视图。下面是一个简化版的实现&#xff0c;用于帮助你理解基本的路由机制。 创建一个简单的 V…

Redis 服务器:核心功能与优化实践

Redis 服务器:核心功能与优化实践 引言 Redis(Remote Dictionary Server)是一款高性能的键值对存储系统,广泛用于缓存、消息队列、实时排行榜等场景。本文将深入探讨Redis服务器的核心功能,并提供一些优化实践的技巧,以帮助读者更好地理解和运用Redis。 Redis的核心功…

openEuler24.03 LTS下安装MySQL8

前提条件 拥有openEuler24.03 LTS环境&#xff0c;可参考&#xff1a;Vmware下安装openEuler24.03 LTS 步骤 卸载原有mysql及mariadb sudo systemctl stop mysql mysqld 2>/dev/null sudo rpm -qa | grep -i mysql\|mariadb | xargs -n1 sudo rpm -e --nodeps 2>/dev/…

GLOW-TTS

我首先需要理解用户的指令&#xff0c;用户希望我翻译文章的3.1节“Training and Inference Procedures”部分。为了完成这个任务&#xff0c;我需要仔细阅读文章的3.1节&#xff0c;理解其中的技术细节和概念&#xff0c;然后将这些内容准确地翻译成中文。 在阅读3.1节时&…

【算法思想】高精度

引入 首先了解&#xff1a; 1. int 范围为10^9 2. long long 范围数量级为10^18 如果超过该数量级&#xff0c;该怎么办&#xff1f; ——这就是高精度、大数的算法问题 加法 输入两个整数a,b,输出他们的和&#xff08;<10的500次方&#xff09; 核心是加法的核心——》每…

【失败了】LazyGraphRAG利用本地ollama提供Embedding model服务和火山引擎的deepseek API构建本地知识库

LazyGraphRAG测试结果如下 数据&#xff1a; curl https://www.gutenberg.org/cache/epub/24022/pg24022.txt -o ./ragtest/input/book.txt 失败了 气死我也&#xff01;&#xff01;&#xff01;对deepseek-V3也不是很友好啊&#xff0c;我没钱prompt 微调啊&#xff0c;晕死…

ccfcsp3402矩阵重塑(其二)

//矩阵重塑&#xff08;其二&#xff09; #include<iostream> using namespace std; int main(){int n,m,t;cin>>n>>m>>t;int c[10000][10000];int s0,sum0;int d[10000],k[100000];for(int i0;i<n;i){for(int j0;j<m;j){cin>>c[i][j];d[s…

算法-除自身以外数组的乘积

力扣题目&#xff1a;238. 除自身以外数组的乘积 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums…

Unity Shader - UI Sprite Shader之简单抠图效果

Sprite抠图效果&#xff1a; 前言 在PhotoShop中我们经常会用到抠图操作&#xff0c;现在就用Shader实现一个简单的抠图效果。 实现原理&#xff1a; 使用当前像素颜色与需要抠掉的颜色相减作比较&#xff0c;然后与一个指定的阈值比较以决定是否将其显示出来&#xff1b; U…

【Mac】安装 Parallels Desktop、Windows、Rocky Linux

一、安装PD 理论上&#xff0c;PD只支持试用15天&#xff01;当然&#xff0c;你懂的。 第一步&#xff0c;在 Parallels Desktop for Mac 官网 下载 Install Parallels Desktop.dmg第二步&#xff0c;双击 Install Parallels Desktop.dmg 第三步&#xff0c;双击安装Paralle…

学习单片机需要多长时间才能进行简单的项目开发?

之前有老铁问我&#xff0c;学单片机到底要多久&#xff0c;才能进行简单的项目开发&#xff1f;是三个月速成&#xff0c;还是三年磨一剑&#xff1f; 今天咱们就来聊聊这个话题&#xff0c;我不是什么高高在上的专家&#xff0c;就是个踩过无数坑、烧过几块板子的“技术老友”…