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

netty入门-5 ServerBootstrap与Bootstarp

前言

本来这篇应该紧接着说明FuturePromise
但是考虑前文第三篇即用到了ServerBootstrap来启动一个服务器,并且我读的闪电侠netty,先写的服务器与客户端启动这部分。索性就先写出来了。主要内容来自闪电侠netty

ServerBootstrap

ServerBootstrap就是一个辅助我们把服务器拉起来的辅助类,怎么用直接看下面。

服务器编写

解释全写在注释里,方便看。
示例程序是书里的。

public class NettyServer{public static  void  main(String[] args){//下面我们可以看到用了两个EventLoopGroup,一个作为boss,一个作为worker。//boss内的EventLoop负责处理连接请求。//worker中则是负责连接后的channel的io请求处理。NioEventLoopGroup  bossGroup  =  newNioEventLoopGroup();NioEventLoopGroup  workerGroup  =  newNioEventLoopGroup();ServerBootstrap  serverBootstrap  =  newServerBootstrap();serverBootstrap.group(bossGroup,  workerGroup)//给服务器指定boss和worker。两个线程组职能分离.channel(NioServerSocketChannel.class)//这里使用NIO类型的ServerSocketChannel。也有其他类型,不过常用NIO类型的。//childHandler之前第三篇文章说过,child指代ServerSocketChannel处理连接请求后产生的新的SocketChannel,所以childHandler表示对服务器连接的Channel添加的处理器。也即对Channel的数据读写如何进行处理。第三篇文章讲到了。.childHandler(newChannelInitializer<NioSocketChannel>(){protectedvoid  initChannel(NioSocketChannel  ch){}})//绑定一个端口serverBootstrap.bind(8000);}
}

梳理一下就是用ServerBootstrap 类,指定groupIo模型channel),写新连接的读写处理逻辑,绑定端口。

这里注意bind操作是一个异步操作
且我们要绑定的端口可能已经被其他应用占用了。所以需要我们递增寻找一个没有被占用的端口。
我们在第四篇文章中说到有这个ChannelFuture处理异步结果。
而这个bind也是一个异步操作,也会返回一个ChannelFuture
我们正好可以对bind操作产生的`ChannelFuture添加一个回调,来进行递增寻找端口的操作。

端口递增绑定

比如端口9000被占用了,我们要继续去bind 9001,直到找到一个可用端口。

//下面代码是一个框架,可以通过future的状态来做不同处理(关于future的状态,下篇来讲,这里可以理解为通过isSuccess()可以了解到bind操作是否成功)
//成功不用多说,失败了就要递增访问端口号。
serverBootstrap.bind(8000).addListener((ChannelFutureListener) future -> {if(future.isSuccess()){}else{serverBootstrap.bind(8001);}
})//书里这个代码挺妙的
//我们发现直接在else部分写一个bind操作似乎不行,因为这个bind操作做完失败的话我们就没有后续了。
//抽象一下,似乎无限复制代码在else部分再写一个bind(8000).addListener..,然后在其内部再写一个逻辑判断,再进行bind。
//失败就不断调用本身,递归思想private static void Bind(ServerBootstrap serverBootstrap, int port){serverBootstrap.bind(8000).addListener((ChannelFutureListener) future -> {if(future.isSuccess()){system.out.println("端口 " + port +"绑定成功" );}else{system.out.println("端口 " + port +"绑定失败" );Bind(serverBootstrap,port+1);	}})
} 

其他方法

这些方法课上确实没咋说,书里这里带了一笔。

//handler方法,和上文的childHandler一样,第三篇文章说到了。
//childHandler用于给新Channel指定读写操作的处理逻辑
//handler就是给服务器启动过程指定一些逻辑。通常用不到
serverBootstrap.handler(newChannelInitializer<NioServerSocketChannel>(){protected void initChannel(NioServerSocketChannel  ch)  {System.out.println("服务端启动中")}
})//attr和childAttr两个方法都是给Channel添加一个键值对。attr是给ServerSocketChannel的。childAttr是给所有正常连接channel的。
//即Channel内部会维护一个Map存储这些键值对。要取可以再用attr或者childAttr,根据键来取属性值
serverBootstrap.attr(AttributeKey.newInstance("serverName"),  "nettyServer")
serverBootstrap.childAttr(AttributeKey.newInstance("clientKey"),  "clientValue")//option和childOption方法是设置TCP参数的。
//同样一个针对ServerSocketChannel。childOption针对其他正常连接channel
//书中给了几个例子
serverBootstrap
//表示系统用于临时存放已完成三次握手的请求的队列的最大长度,如果连接建立频繁,服务器处理创建新连接较慢,则可以适当调大这个参数。
.option(ChannelOption.SO_BACKLOG,  1024)
//ChannelOption.SO_KEEPALIVE表示是否开启TCP底层心跳机制,true表示开启。
.childOption(ChannelOption.SO_KEEPALIVE,  true)
//ChannelOption.TCP_NODELAY表示是否开启Nagle算法,true表示关闭,false表示开启。通俗地说,如果要求高实时性,有数据发送时就马上发送,就设置为关闭;如果需要减少发送次数,减少网络交互,就设置为开启。
.childOption(ChannelOption.TCP_NODELAY,  true)

Bootstarp

ServerBootstrap类似,不过Bootstrap是用于启动客户端的辅助类。

客户端启动

同样是指定线程模型(group),IO模型(NioSocketChannel),IO操作处理逻辑(handler)。
其实同服务器启动基本一致。
不过这里书里提到了连接失败的重试处理。我们来看看

NioEventLoopGroup  workerGroup  =  newNioEventLoopGroup()Bootstrap  bootstrap  =  newBootstrap();
bootstrap
//  1.指定线程模型
.group(workerGroup)
//  2.指定IO  类型为NIO
.channel(NioSocketChannel.class)
//  3.IO 处理逻辑
.handler(newChannelInitializer<SocketChannel>(){@Overridepublicvoid  initChannel(SocketChannel  ch){}
});
//  4.建立连接
bootstrap.connect("juejin.cn",  80).addListener(future  ->if(future.isSuccess()){System.out.println("连接成功!");}else{System.err.println("连接失败!");}
});
//我们见到与上面服务器创建时,我们要做端口递增绑定类似的部分。
//这里原理类似,因为connect与bind都是异步方法,所以我们要写好异步回调,表明在异步操作成功后做什么,失败后做什么
//connect失败说明连接失败。我们可以用重试,一定次数后放弃连接,并且不会在失败后立即重连,指数增长重试事件,如1秒,2秒,4秒,8秒等。默认次数设为5次下面是实现逻辑。
//也采用封装一个递归函数来递归调用的方法。
private static void connect(Bootstrap bootstrap,String host,int port,int retry){bootstrap.connect(host,  port).addListener(future ->{if(future.isSuccess()){System.out.println("连接成功!");}else if(retry  ==  0) {System.err.println("重试次数已用完,放弃连接!");}else{//  第几次重连int  order  =  (MAX_RETRY  -  retry)  +  1;//  本次重连的间隔int  delay  =  1  <<  order;System.err.println(newDate()  +  ":连接失败,第"  +  order  +  "次重连……");bootstrap.config().group().schedule(()  ->  connect(bootstrap,  host,  port,retry--),  delay,  TimeUnit.SECONDS);}});
} 

上面代码比较好懂,
不过这里等待一定时间后执行任务的操作,即定时任务操作,用了bootstrap.config().group().schedule()来做。
group()返回我们配置的workerGroupschedule()正是其中的方法,来定时执行一个任务。
在上面最后的else中,根据剩余重试次数retry,来确定本次重试之前要等多长时间,即delay,再通过schedule()递归调用函数本身,不过递归函数的参数retry要减1,因为它代表剩余重试次数。

其他方法

ServerBootstrap一样,Bootstrap也有attr方法来给Channel设置键值对。不再赘述。
也有option方法来设置TCP参数。
书中给了如下参数

.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,  5000)
.option(ChannelOption.SO_KEEPALIVE,  true)
.option(ChannelOption.TCP_NODELAY,  true)

ChannelOption.CONNECT_TIMEOUT_MILLIS表示连接的超时时间,超过这个时间,如果仍未连接到服务端,则表示连接失败。
ChannelOption.SO_KEEPALIVE表示是否开启TCP底层心跳机制,true表示开启。
ChannelOption.TCP_NODELAY表示是否开始Nagle算法,true表示关闭,false表示开启。通俗地说,如果要求高实时性,有数据发送时就马上发送,就设置为true;如果需要减少发送次数,减少网络交互,就设置为false

结语

本文内容均来自《跟着闪电侠学Netty》。
看了看书,感觉挺有帮助的。技术还是视频,书籍,源码,实践相辅相成好。

本篇仅是对ServerBootstrapBootstrap的补充说明,后续还会按视频课程的编排来写。中间穿插一些书中写到但是视频没有提到的东西。

下篇就是开头说要写的PromiseFuture了。篇幅应该不长,只写一点。
按顺序再后面应该是handlerpipeline,还有ByteBuf

这里稍微说下,这本书里的内容其实和课程中很多部分都是重复的,毕竟说的都是Netty吗。
然后我对比了一下二者的基础部分,书接下来讲的通信协议编解码,PipelineChannelHandler,粘包拆包,双向通信。实现一个简单群聊。这些视频同样讲到了。可能有几个章节是二者独有的。二者可以对比学习。效果应该会更好吧。

后面写我尽量结合两边来写。

感谢阅读,欢迎批评指正。

相关文章:

netty入门-5 ServerBootstrap与Bootstarp

前言 本来这篇应该紧接着说明Future和Promise。 但是考虑前文第三篇即用到了ServerBootstrap来启动一个服务器&#xff0c;并且我读的闪电侠netty&#xff0c;先写的服务器与客户端启动这部分。索性就先写出来了。主要内容来自闪电侠netty ServerBootstrap ServerBootstrap就…...

JavaEE - Spring Boot 简介

1.Maven 1.1 什么是Maven 翻译过来就是: Maven是⼀个项⽬管理⼯具。基于POM(Project Object Model,项⽬对象模型)的概念&#xff0c;Maven可以通 过⼀⼩段描述信息来管理项⽬的构建&#xff0c;报告和⽂档的项⽬管理⼯具软件。 可以理解为&#xff1a;Maven是一个项目管理工具…...

SwiftUI革新:Xcode UI开发的新纪元

SwiftUI革新&#xff1a;Xcode UI开发的新纪元 SwiftUI作为Apple推出的声明式UI框架&#xff0c;彻底改变了在Xcode中构建用户界面的方式。它不仅简化了代码&#xff0c;还提高了开发效率&#xff0c;并且使得UI设计更加直观和灵活。本文将深入探讨如何在Xcode中使用SwiftUI进…...

22、基于共享内存的数据结构——用十个块来提高并发性

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 为了提高并发性&#xff0c;把…...

【ffmpeg命令入门】实现画中画

文章目录 前言画中画是什么画中画的外观描述效果展示为什么要用画中画应用场景示例 使用FFmpeg添加画中画示例命令参数解释调整嵌入视频的位置调整嵌入视频的大小处理音频 总结 前言 FFmpeg 是一款强大的多媒体处理工具&#xff0c;广泛用于音视频的录制、转换和流处理。它不仅…...

基于 LangChain+LangGraph 来实现一个翻译项目

相信大家在看文档的时候&#xff0c;有时会比较苦恼&#xff0c;比如 AI 相关的文档都是外文&#xff0c;中文文档比较少&#xff0c;看起来会比较吃力&#xff0c;有的时候会看不懂&#xff0c;翻译软件又翻得很乱&#xff0c;完全看不了&#xff0c;今天就基于 LangChain 和 …...

javascript 如何将 json 格式数组转为 excel 表格| sheetJS

案例 // https://unpkg.com/xlsx0.18.5/dist/xlsx.full.min.js function exportXlsx(jsonData, fileName , mine null) {const workbook XLSX.utils.book_new();// 将JSON数组转换成工作表const worksheet XLSX.utils.json_to_sheet(jsonData);// 向工作簿添加工作表XLSX.…...

网页制作技术在未来会如何影响人们的生活?

网页制作技术在未来会如何影响人们的生活&#xff1f; 李升伟 网页制作技术在未来可能会从以下几个方面显著影响人们的生活&#xff1a; 1. 工作与学习方式的变革&#xff1a;远程办公和在线教育将更加普及和高效。通过精心制作的网页&#xff0c;人们能够实现更便捷的协作…...

【计算机网络】网络层——IPv4地址(个人笔记)

学习日期&#xff1a;2024.7.24 内容摘要&#xff1a;IPv4地址&#xff0c;分类编址&#xff0c;子网&#xff0c;无分类编址 IPv4地址概述 在TCP/IP体系中&#xff0c;IP地址是一个最基本的概念&#xff0c;IPv4地址就是给因特网上的每一台主机的每一个接口分配一个在全世界…...

c++ 学习笔记之多线程:线程锁,条件变量,唤醒指定线程

基于CAS线程加锁方式 CAS&#xff08;Compare-And-Swap&#xff09;和 mutex 都是用于实现线程安全的技术&#xff0c;但它们适用于不同的场景&#xff0c;具有不同的性能和复杂性。下面是对两者的区别和使用场景的详细解释&#xff1a; CAS&#xff08;Compare-And-Swap&…...

《0基础》学习Python——第二十三讲__网络爬虫/<6>爬取哔哩哔哩视频

一、在B站上爬取一段视频&#xff08;B站视频有音频和视频两个部分&#xff09; 1、获取URL 注意&#xff1a;很多平台都有反爬取的机制&#xff0c;B站也不例外 首先按下F12找到第一条复制URL 2、UA伪装&#xff0c;下列图片中&#xff08;注意代码书写格式&#xff09; 3、Co…...

第13周 简历职位功能开发与Zookeeper实战

第13周 简历职位功能开发与Zookeeper实战 本章概述1. Mysql8窗口函数over使用1.1 演示表结构与数据1.2 案例1:获取男女总分数1.3 案例2****************************************************************************************本章概述 1. Mysql8窗口函数over使用 参考案例…...

什么是大型语言模型 (LLM)

本章探讨下&#xff0c;人工智能如何彻底改变我们理解和与语言互动的方式 大型语言模型 (LLM) 代表了人工智能的突破&#xff0c;它采用具有广泛参数的神经网络技术进行高级语言处理。 本文探讨了 LLM 的演变、架构、应用和挑战&#xff0c;重点关注其在自然语言处理 (NLP) 领…...

【人工智能】AI时代:探索个人潜能的新视角

文章目录 &#x1f34a;Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉1.5.2 局限二&#xff1a;Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 …...

pyaudio VAD通过声音音频值分贝大小检测没人说话自动停止录制

效果可能说话声音小可能不被监听到,需要更改QUIET_DB阈值,另外delay_time值是低于阈值多久就可以停止保存当前的语音 import pyaudio import waveimport sys import numpy as npdef record_auto(MIC_INDEX=1):开启麦克风录音,保存至temp/speech_record.wav音频文件音量超过…...

《后端程序猿 · @Value 注释说明》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

【LeetCode】71.简化路径

1. 题目 2. 分析 3. 代码 我写了一版很复杂的代码&#xff1a; class Solution:def simplifyPath(self, path: str) -> str:operator [] # 操作符的栈dir_name [] # 文件名的栈idx 0cur_dir_name ""while(idx < len(path)):if path[idx] /:operator.ap…...

DockerCompose 安装环境

1. Redis version: 3 services:redis:image: redis:6.2.12container_name: redisports:- "6379:6379"environment:TZ: Asia/Shanghaivolumes:# 本地数据目录要先执行 chmod 777 /usr/local/docker/redis/data 赋予读写权限&#xff0c;否则将无法写入数据- /usr/loc…...

学习笔记之JAVA篇(0724)

p 方法 方法声明格式&#xff1a; [修饰符1 修饰符2 ...] 返回值类型 方法名&#xff08;形式参数列表&#xff09;{ java语句;......; } 方法调用方式 普通方法对象.方法名&#xff08;实参列表&#xff09;静态方法类名.方法名&#xff08;实参列表&#xff09; 方法的详…...

【Android】广播机制

【Android】广播机制 前言 广播机制是Android中一种非常重要的通信机制&#xff0c;用于在应用程序之间或应用程序的不同组件之间传递信息。广播可以是系统广播&#xff0c;也可以是自定义广播。广播机制主要包括标准广播和有序广播两种类型。 简介 在Android中&#xff0c…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...

RKNN开发环境搭建2-RKNN Model Zoo 环境搭建

目录 1.简介2.环境搭建2.1 启动 docker 环境2.2 安装依赖工具2.3 下载 RKNN Model Zoo2.4 RKNN模型转化2.5编译C++1.简介 RKNN Model Zoo基于 RKNPU SDK 工具链开发, 提供了目前主流算法的部署例程. 例程包含导出RKNN模型, 使用 Python API, CAPI 推理 RKNN 模型的流程.   本…...

分布式计算框架学习笔记

一、&#x1f310; 为什么需要分布式计算框架&#xff1f; 资源受限&#xff1a;单台机器 CPU/GPU 内存有限。 任务复杂&#xff1a;模型训练、数据处理、仿真并发等任务耗时严重。 并行优化&#xff1a;通过任务拆分和并行执行提升效率。 可扩展部署&#xff1a;适配从本地…...

Java求职者面试:微服务技术与源码原理深度解析

Java求职者面试&#xff1a;微服务技术与源码原理深度解析 第一轮&#xff1a;基础概念问题 1. 请解释什么是微服务架构&#xff0c;并说明其优势和挑战。 微服务架构是一种将单体应用拆分为多个小型、独立的服务的软件开发方法。每个服务都运行在自己的进程中&#xff0c;并…...