Modbus协议介绍及Modbus TCP

这里写目录标题 一、Modbus起源1.起源2.分类3.优势4.应用场景5.ModbusTCP特点⭐⭐⭐ 二、Modbus TCP协议格式1.报文头2.寄存器3.功能码4.协议包书写模板总结 一、Modbus起源 1.起源 Modbus由Modicon公司于1979年开发,是一种工业现场总线协议标准。 Modbus通信协议具有多个变种,其中有支持串口,以太网多个版本,其中最著名的是Modbus RTU、Modbus ASCII和Modbus TCP三种 其中Modbus TCP是在施耐德收购Modicon后1997年发布的。 2.分类 1)Modbus RTU 运行在串口上的协议,采用二进制的表现形式以及紧凑型数据结构,通信效率高,应用比较广泛 2)Modbus ASCII 运行在串口上的协议,采用ASCII码进行传输,并且利用特殊字符作为字节开始和结束的标志,传输效率远远低于Modbus RTU ,只有通信数据量比较少时才会考虑它 3)Modbus TCP 运行在以太网上的协议 3.优势 免费、简单、容易使用 4.应用场景 Modbus协议是现在国内工业领域应用最多的协议,不只PLC设备,各种终端设备,比如水控机、水表、电表、工业秤、各种采集设备 5.ModbusTCP特点⭐⭐⭐ 1)采用主从问答方式通信 2)Modbus TCP协议属于应用层协议,基于传输层TCP进行传输 3)Modbus TCP默认端口号502 二、Modbus TCP协议格式 ModbusTcp协议包含三部分:报文头、功能码、数据 Modbus TCP/IP协议最大数据帧长度为260字节 1.报文头 包含7个字节,分别是: 2.寄存器 寄存器分类:线圈、离散量输入、保持寄存器、输入寄存器 1)离散量和线圈 其实就是位寄存器(每个寄存器数据占1字节),工业上主要用于控制IO设备。 线圈寄存器,类比为开关量,每一个bit都对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。 对应上面的功能码也就是:0x01 0x05 0x0f离散输入寄存器,离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。 所以功能码也简单就一个读的 0x02 2)输入和保持寄存器是字寄存器(每个寄存器数据占2个字节),工业上主要用于存储工业设备的值。 保持寄存器,这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写 所以功能码有对应的三个:0x03 0x06 0x10输入寄存器,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值 对应的功能码也就一个 0x04 📢线圈寄存和保持寄存器是可读可写的,离散输入寄存器和输入寄存器只能读不可写。 3.功能码 4.协议包书写模板总结 读操作 主机->从机: 报文头(7字节) + 功能码(1字节) + 起始地址(2字节) + 数量(2字节)

Android | ADB 命令

Android Debug Bridge Android 调试桥,通过 C/S 的形式利用 PC 来操作 Android 设备,通过 ADB 可以利用 shell 直接操作真机或模拟器,比如传输文件、管理应用、拉取日志等。 常用的 ADB 指令 # 开启 ADB 服务 adb start-server # 停止 ADB 服务 adb kill-server # 连接设备 adb connect xxx # 查看连接设备 adb devices # 安装应用 adb install xxx.apk # 卸载应用 adb uninstall com.xxx.xxx # 卸载应用 但保存缓存与数据 adb uninstall -k com.xxx.xxx # 清除应用缓存与数据 adb pm clean com.xxx.xxx # 列出已安装 APP 包名 # -s 系统应用 # -3 三方应用 adb shell pm list packages [-s | -3] # 查看当前界面是哪个 Activity adb shell dumpsys activity top | grep ACTIVITY # 截屏并存入本地 adb exec-out screencap -p > xxx.

【K8S系列】深入解析k8s网络插件—Canal

序言 做一件事并不难,难的是在于坚持。坚持一下也不难,难的是坚持到底。 文章标记颜色说明: 黄色:重要标题红色:用来标记结论绿色:用来标记论点蓝色:用来标记论点 在现代容器化应用程序的世界中,容器编排平台Kubernetes已经成为标准。Kubernetes是一个分布式系统,为了支持复杂的应用和微服务架构,网络是Kubernetes集群中不可或缺的一部分。 能够管理和编排容器化应用程序,其中,监控是一个非常重要的方面,可以帮助用户了解集群的健康状态、性能和可用性。 在本文中,将详细介绍Kubernetes网络插件中的【Canal】插件。 希望这篇文章能让你不仅有一定的收获,而且可以愉快的学习,如果有什么建议,都可以留言和我交流 专栏介绍 这是这篇文章所在的专栏,欢迎订阅:【深入解析k8s】专栏 简单介绍一下这个专栏要做的事: 主要是深入解析每个知识点,帮助大家完全掌握k8s,以下是已更新的章节这是专栏介绍文章地址:【深入解析K8S专栏介绍】 1 基础介绍 在Kubernetes中,网络插件也称为容器网络接口(Container Network Interface,CNI)插件,用于实现容器之间的通信和网络连接。以下是一些常见的Kubernetes网络插件: Flannel:Flannel是一个流行的CNI插件,它使用虚拟网络覆盖技术(overlay network)来连接不同节点上的容器。Flannel支持多种后端驱动,如VXLAN、UDP、Host-GW等。 Calico:Calico是一个开源的网络和安全解决方案,它使用BGP协议来实现容器之间的路由。Calico支持灵活的网络策略和安全规则,可用于大规模部署。 Weave Net:Weave Net是一个轻量级的CNI插件,通过创建虚拟网络设备和网络代理来连接不同节点上的容器。Weave Net支持overlay模式和直连模式,具有灵活性。 Cilium:Cilium是面向Kubernetes的高性能网络和安全解决方案,利用eBPF(Extended Berkeley Packet Filter)技术来提供快速的容器间通信和网络策略实施。 Canal:Canal是一个综合性的CNI插件,结合了Calico和Flannel的功能。它可以使用Flannel提供overlay网络,同时使用Calico的网络策略和安全性功能。 Antrea:Antrea是一个基于Open vSwitch的CNI插件,专为Kubernetes网络和安全性而设计。它提供了高性能的网络连接和网络策略功能。 kube-router:kube-router是一个开源的CNI插件,它结合了网络和服务代理功能。它支持BGP和IPIP协议,并具有负载均衡的特性。 这些是Kubernetes网络插件中的一些常见选项,每个插件都有其特定的优势和适用场景。选择合适的网络插件取决于你的需求、网络拓扑和性能要求等因素。 同时,Kubernetes社区也在不断发展和推出新的网络插件,以满足不断变化的需求。 2 Canal 介绍 2.1 概念介绍 Canal是一个基于MySQL协议的网络插件,它可以将MySQL数据库的binlog事件同步到Kubernetes集群中的其他资源,如Pod、Service等。 这意味着,通过Canal,我们可以实现MySQL数据库与Kubernetes集群的无缝集成。 Canal的核心概念主要包括以下几个方面: 数据流:Canal的核心是数据的流动。它通过监听MySQL数据库的binlog事件,将这些事件转换为Kubernetes可以理解的数据格式,然后将这些数据发送到指定的Kubernetes资源。 事件转换:Canal提供了一套完整的事件转换规则,可以将MySQL的binlog事件转换为Kubernetes的资源对象。这样,我们就可以通过Kubernetes API来管理和操作这些资源。 数据持久化:为了确保数据的完整性和一致性,Canal提供了数据持久化功能。它会将接收到的数据存储在本地,当需要时,可以从本地读取数据,或者将数据写入到MySQL数据库。 下面是 Canal 的其他介绍: 网络功能:Canal 可以为 Kubernetes 集群提供网络功能,包括网络互联、网络隔离和路由等。它实现了一个软件定义网络(SDN)解决方案,通过创建虚拟网络和网络策略,使得容器和 Pod 可以相互通信,并能与集群外的网络进行连接。 网络隔离:Canal 具备强大的网络隔离能力,可以将 Kubernetes 集群中的不同命名空间或不同 Pod 组进行隔离,防止它们之间的通信。这种隔离能力可以帮助用户实现多租户环境下的安全和性能隔离。 网络路由:Canal 可以为 Kubernetes 集群提供灵活的网络路由功能。它支持基于 IP 地址和端口的负载均衡,可以根据用户定义的规则将流量引导到不同的 Pod 或服务上,从而实现高可用和负载均衡。

文件没有更改,但git status显示modified

背景 在windows下编辑某个项目代码时,编辑到一半,需要切换到另一个分支,直接转换会提示当前工作区还有已修改的文件尚未commit,但是当前更改的内容尚未完整,所以还不想commit到仓库中。所以就使用了git stash save命令将当前工作区缓存后,才能切换到其他分支。 但是在checkout回到自己分支使用git stash apply时。发现不能将stash中的内容恢复,报错显示有文件已modified,即使使用girl restore xxx也没办法将文件的modified状态消除。 问题排查 首先,因为确认没有对文件做了什么修改,所以我一开始先直接使用git restore命令将文件恢复到上次提交的内容,但是发现没有什么用,文件还是处于modified状态git restore example/example.py 接着,我使用git diff --summary对比modified文件到底发生了什么变化$ git diff --summary mode change 100755 => 100644 example/example.py 根据提示,发现是文件的权限发生了改变,参考中的方式,在git bash中运行了以下命令,但是没起作用,不知道是不是因为是系统是windows的原因git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | tr '\n' '\0' | xargs -0 chmod +x 最后,通过git config --list才发现,config中有一条filemode配置项,该配置项被设置为了true状态$ git config --list ... core.filemode=true ... 修改该配置项的值为false, 文件的modified状态消失了。git config core.filemode false 这样设置作用范围仅针对当前工作区,如果想要全局生效,则需要添加--global选项git config --global core.

对象内存布局与对象头

对象内存布局 在Hotspot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据、对齐填充。 对象头 在64为系统中,Mark word 占了8个字节,cla ss Pointer 占了8个字节。从jdk1.8开始,存在指针压缩,class Pointer 占4个字节。 jvm默认开启的:-XX:+UserCompressedClassPointers 压缩指针 对象标记 Mark Word 存储着:hash码、gc标记、gc次数(年龄)、同步锁标记、偏向锁持有者 gc的分代年龄只有4位,所以最大年龄15 类元信息(类型指针class Pointer) 类元信息就是new 某个对象的模板,即ObjectDemo1 o1 = new ObjectDemo1(); 的ObjectDemo1。 里面的属性为实例数据。 对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是那个类的实例。 class Resouce{ //只含对象头 } class Book{//有实例数据,16字节(忽略指针压缩)+ 4字节 + 1字节 = 21字节,由于对齐填充为24字节 int id; boolean flag; } 实例数据 存放类的属性(field)数据信息,包括父类属性信息。 对齐填充 虚拟机要求对象起始地址必须是8字节的整数倍。它的存在不是必须的,仅仅是为了字节对齐这部分内存按照8字节补充对齐。

移植LVGL到Linux

前言 最近在板子上调试的时候用到Lvgl,这里记录一下把Lvgl V8.1移植到linux上的过程 一、准备工作 准备好所用板子的交叉编译环境带LCD的linux开发板,调通LCD驱动Lvgl源码 在github上搜索Lvgl https://github.com/lvgl ,找到以下仓库并下载:Lvgl (下载lvgl-release-v8.1 )lv_demos (下载lv_demos-release-v8.1)lv_drivers (下载lv_drivers-release-v8.1)lv_port_linux_frame_buffer (下载lv_port_linux_frame_buffer-release-v8.2) (需要说明的是,一开始下的是master分支的最新代码,但是编译的时候发现lv_disp_drv_t没有定义(error: unknown type name ‘lv_disp_drv_t’),看了下其他版本的源码,是在lvgl\src\hal\lv_hal_disp.h下定义的,但是下载的lvgl源码里并没有找到相关的文件和定义,于是就下载最新的release版本 lvgl-release-v8.1) 二、开始移植 1.在Ubuntu下创建目录lvgl_demo_test并移入相应的文件 把lvgl-release-v8.1复制进文件夹lvgl_demo_test,重命名为lvgl;把lv_drivers-release-v8.1复制进文件夹lvgl_demo_test,重命名为lv_drivers;把lv_demos-release-v8.1复制进文件夹lvgl_demo_test,重命名为lv_demo;从lvgl中复制lv_conf_template.h到lvgl_demo_test,并重命名为lv_conf.h;从lv_drivers中复制lv_drv_conf_template.h到lvgl_demo_test,并重命名为lv_drv_conf.h;从lv_demo中复制lv_demo_conf_template.h到lvgl_demo_test,并重命名为lv_demo_conf.h;从lv_port_linux_frame_buffer-release-v8.2中复制main.c和Makefile到lvgl_demo_test下 2.修改配置文件 修改lv_conf.h 改成#if 1使能头文件的内容 根据驱动(可在设备树中查看)选择像素点对应像素格式的大小,否则显示可能乱码 修改显存大小 修改刷新周期,根据所用处理器的性能调整 设置Tick定时器配置函数 使能用到的字体,不然编译会提示未定义 如果需要查看log,使能LV_USE_LOG,设置打印的log等级并选择打印Log的接口 修改lv_drv_conf.h 改成#if 1 使能头文件的内容: 使能LCD显示:使能USE_FBDEV,路径设置成/dev/fb0,根据板子LCD的实际情况设置 使能触摸屏输入: 修改lv_demo_conf.h 改成#if 1 使能头文件的内容 使能要移植的demo,这里使能的是LV_USE_DEMO_WIDGETS 2.修改main.c 设置正确的lv_demo.h头文件路径 设置DISP_BUF_SIZE 根据LCD像素尺寸修改驱动参数,我使用的屏幕是800*480像素的 当前没有使用到鼠标,注释掉相关代码 lv_demo_widgets()是所移植的demo的入口 3.修改Makefile 配置交叉编译器 编入lv_demo mouse没用到,注释掉 我用的编译器版本不支持 -Wshift-negative-value这个参数,在Makefle里去掉了 三、编译运行 编译 在lv_demo_test目录下,输入make即可编译,编译后在当前目录下生成可执行文件demo运行 把demo复制到开发板上,输入./demo即可运行

信创简单了解

信创:信息技术应用创新产业,其是数据安全,网络安全的基础,也是新基建的重要组成部分。 信创涉及的行业包括IT基础设施:CPU芯片,服务器,存储,交换机,路由器,各种云等。基础软件:数据库,操作系统,中间件。应用软件:OA,ERP,办公软件,政务应用。信息安全:硬件安全,软件安全,安全服务(边界安全产品,终端安全产品)。 最主要的是使国内信创产业形成自有开放生态。 方法:资源扶持;加强产品研发和营销推广 国产化:技术引进项目投产后所生产的产品中,国内生产件的数量占整体产品生产件的数量比例。 国产化率:价值/重量衡量----国内生产件的价格/重量占整体生产件的比例 IT基础设施: CPU: 国外CPU:AMD,英特尔,苹果 CPU的分类还可以按照指令集的方式将其分为精简指令集计算机(RISC)和复杂指令集计算机(CISC)。 典型的CISC指令集有x86微架构,典型的RISC指令集有ARM微架构 目前,龙芯引进MIPS指令集并在其基础上开发LoongArch指令集,申威则是在Alpha指令集基础上自研了SW-64指令集,海光从AMD获得了x86指令集的永久授权,兆芯从台湾Via也获得x86指令集开发权,鲲鹏和飞腾拿到ARM v8授权。 龙芯中科 ,中科院嫡系部队,自研,学习国外的MIPS指令研发了龙芯自主指令系统LoongArch,LoongArch不包含MIPS指令系统的内容,亦无需取得MIPS公司任何授权许可。产品有3A4000 3B4000 3A5000 3B5000 3C5000L 3D5000 由于LoongArch指令集与主流指令集不兼容,需要软硬件厂商围绕LoongArch指令集,编译适配成龙芯能“听懂”的产品。龙芯计划推出LoongArch到x86和ARM指令集的转译器,从而兼容x86和ARM的生态。 飞腾 目前是国资比例最高(CEC通过中国长城控股)的国产CPU企业。基于ARM V8架构永久授权。无法获得ARM v9最新版本授权,后续产品研发迭代前景堪忧。 飞腾CPU主要包括高效能桌面CPU、高性能服务器CPU、高端嵌入式CPU和飞腾套片四大系列。高性能服务器CPU产品线统一以飞腾“腾云S系列”进行命名;高效能桌面CPU产品线统一以飞腾“腾锐D系列”进行命名;高端嵌入式CPU产品线统一以飞腾“腾珑E系列”进行命名。 盘古 华为系列产品,网上资料不详,性能可能较差,ARM架构海光 海光是国内高性能计算机龙头中科曙光的参股子公司。X86架构,X86授权,海光拥有X86指令集永久授权,基于交叉授权模式,迭代灵活度大,但只能面向国内市场。与AMD签署了《技术许可协议》。 2019年6月,海光信息被列入美国《出口管制条例》“实体清单”,此后AMD不再提供相关技术服务,公司自行实现了后续产品和技术的迭代开发。后续海光经过多年的研发创新,已经具备自主设计优化处理器微架构与指令集的能力,独立开发迭代三代产品并实现商业化应用,海光最新代产品性能已经超过AMD ZEN 2水平,接近ZEN 3的性能表现。兆芯 ,上海市国资委下属企业和台湾威盛电子合资成立,X86架构,X86授权,授权来自台湾威盛,已于2018年过期,未续约,存在法律风险。 兆芯的授权是从威盛那获得的,威盛将自己的X86技术,专利、团队、以及GPU团队、芯片组团队等并入兆芯,而威盛的X86授权是来自于曾经收购的Cyrix。 不过,还是要提一下,X86指令集也在不断的调整完善,也会增加一些指令集进去。而海光、兆芯获得的授权,是基于之前的授权,并不会实时跟进这些新的指令集,所以这些新的指令集,intel不会再授权给海光、兆芯的。 而Cyrix是拥有X86的永久授权的,所以兆芯拥有的一样是X86的永久授权,不存在被intel回收一说。 5. 申威 授权加自研,基于Alpha指令集拓展了SW-64指令集。申威只专攻军工和政府保密部门 6. 华为鲲鹏 ARM架构,基于ARM V8架构永久授权。无法获得ARM v9最新版本授权,后续产品研发迭代前景堪忧。 华为牵手中国电子,合并鲲鹏、PKS生态。中国电子旗下的飞腾CPU联合麒麟软件,建立了PKS生态。 优缺点: 海光、兆芯采用x86架构,软硬件应用生态优秀 鲲鹏、飞腾采用ARM 架构,由于受到授权条款限制 申威、龙芯则是早期采用Alpha架构及MIPS架构,在党政及特殊市场都有一定的应用 GPU GPU有两条主要的发展路线:分别为传统的2D/3D图形渲染GPU和专注高性能计算的GP GPU。 英伟达每年的GTC大会吸引着众多尖端科技工作者的目光。英伟达的GPU芯片正在为全球绝大多数的人工智能系统提供最基础的算力支持 2022年8月,美国监管机构以国家安全为由,对NVIDIA A100、H100两款GPU实施禁令,不得销售给中国企业,意在通过“卡脖子”的方法来降低国内AI模型的传输速度,拖延中国人工智能发展。而中国能获得的最佳替代品,则是英伟达专供中国的A800芯片,也是A100的“阉割版”,其传输速度只有A100的70%,而在H100大规模供货后,中美AI公司的差距则将进一步拉大。 景嘉微 首先,是借军工信息化之风迈向全面国产替代的GPU企业——景嘉微。 景嘉微的技术核心团队来自于国防科技大学,公司业务也是依靠军工业务图形显控模块芯片起家,持续投入研发布局全自主研发GPU芯片的图形显控传统业务。截止目前,公司是国内首家成功研制国产GPU芯片并实现大规模工程应用的企业,也是国内唯一具备完全自主研发GPU能力并产业化的上市公司,目前已拥有267项专利,在图形显控领域走在行业前列。 海光 海光协处理器(DCU),对标目前国际主流人工智能企业都在使用的NVIDIA A100产品,海光DCU单芯片产品基本能达到其70%的性能水平。深算一号产品。 而在硬件之外,海光信息也为打破CUDA生态专门制作了软件配置:海光 DCU 协处理器全面兼容 ROCm GPU计算生态,由于ROCm与CUDA的高度相似性,CUDA用户可以以较低代价快速迁移至 ROCm平台,因此,海光DCU协处理器能够较好地适配、适应国际主流商业计算软件和人工智能软件,软硬件生态丰富。寒武纪

Nginx代理Jenkins

Jenkins系列文章 一、Jenkins安装配置 二、Jenkins部署springboot项目 三、Jenkins部署前端项目 四、Publish over ssh分发项目 五、Nginx代理Jenkins 1、查看jenkins配置文件位置 systemctl status jenkins 2、修改配置文件中的访问前缀 vim /usr/lib/systemd/system/jenkins.service 找到JENKINS_PREFIX,然后取消注释,将它修改为我们想要使用的前缀即可,这里我们使用默认的jenkins演示,修改完成后,保存退出,重启Jenkins。 3、修改nginx配置文件 在nginx服务器中增加Jenkins的访问代理即可。 location /jenkins { proxy_pass http://ip:port; }

Python项目开发:Flask基于Python的天气数据可视化平台

欢迎大家点赞、收藏、关注、评论 文章目录 前言一、项目介绍二、开发环境三、功能介绍数据库设计概述数据库表的设计 四、核心代码五、效果图六、文章目录 前言 随着社会多元化的不断发展,天气数据问题不可被简单的理解为是科学问题,更多的是环境问题,可以直接影响到人民的日常生活,甚至对一个国家的政治经济带来影响,由此可见,天气预测是一项非常重要的行业。基于此,我们就需要开发一个可视化的、综合的、方便人们查看的项目。基于Python的天气数据可视化设计与实现,通过使用基于Python的网络爬虫技术,能在短时内提取有价值的信息数据。然后根据数据的形式进行整理,运用 HTML、CSS、JavaScript、Flask 框架、Echarts、WordCloud 等技术对数据进行可视化展现,有利于更好地利用数据解决实际问题。 一、项目介绍 天气变幻无常,影响着我们生活的方方面面,应用天气预报信息可以及时了解天气的趋势,给人们的工作、生活等带来便利,也可以为我们为未来的事情做安排和打算,所以一个精准的、易读的、直观的天气信息对我们个人、国家来说都很重要。气象网站中有大量的多维度气象数据信息,供社会各行业作为参考研判的依据,Python作为当前数据分析领域最为流行的语言,具有丰富和强大的库.为数据分析提供大量函数,通过利用Python程序对气象网站大量的气象信息进行分析,可以挖掘出关于气象气候演变的规律信息,为气象预报提供更丰富的参考依据。国内外都专注于各种物理技术对于天气的预报与分析,并没有过多地关于数据的可视化以及收集的研究,大多数产品的功能相差不大,这样获得信息可能比较分散并且不太利于普通人的阅读。但是不管是国内还是国外的这一些已有的方案,都为本课题提供了大量的经验。 基于此,我们就需要开发一个可视化的、综合的、方便人们查看的项目。基于Python的天气数据可视化设计与实现,通过使用基于Python的网络爬虫技术,能在短时内提取有价值的信息数据。然后根据数据的形式进行整理,运用 HTML、CSS、JavaScript、Flask 框架、Echarts、WordCloud 等技术对数据进行可视化展现,有利于更好地利用数据解决实际问题。电子化的管理。 二、开发环境 开发语言:Python 框架:flask Python版本:python3.7.7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:PyCharm 浏览器:谷歌浏览器 ———————————————— 三、功能介绍 根据现实需要,此系统我们设计出一下功能,主要有以下功能模板。 (1)注册登录模块:管理员、用户两端登录对应实现相应功能,每个角色都有自己的账号 密码可以进行登录。 (2)用户端功能:首页、个人中心、天气新闻管理、空气质量指数管理、7天天气管理、生活指数管理、景点推荐管理、系统管理。 (3)管理员功能:首页、个人中心、用户管理、天气新闻管理、空气质量指数管理、7天天气管理、生活指数管理、景点推荐管理、系统管理。 了更好的去理清本系统整体思路,对该系统以结构图的形式表达出来,设计实现该天气数据可视化平台的功能结构图如下所示: 图4-1 系统总体结构图 本系统主要有登录,用户、用户和管理员等部分组成。 登录模块用例中用户和管理员和两种角色,分别可以进行其对应的身份登录或取消登录,关闭系统。登录用例图如图3-1所示。 3-1登录用例图 (2)用户模块主要包括首页、个人中心、天气新闻管理、空气质量指数管理、7天天气管理、生活指数管理、景点推荐管理、系统管理等功能,用户用例图如图3-2所示。 图3-2用户用例图 (3)管理员模块主要包括首页、个人中心、用户管理、天气新闻管理、空气质量指数管理、7天天气管理、生活指数管理、景点推荐管理、系统管理等功能,用户用例图如图3-3所示。 图3-3管理员用例图 数据库设计概述 数据库表的设计 部分数据库展示 (1)表名:tianqixinwen 功能:天气新闻 (2)表名:qitiantianqi 功能:7天天气 四、核心代码 部分代码: def users_login(request): if request.method in ["POST", "GET"]: msg = {'code': normal_code, "msg": mes.normal_code} req_dict = request.session.get("req_dict") if req_dict.get('role')!=None: del req_dict['role'] datas = users.

Spring全家桶相关注解总结

spring相关 @Controller 【控制器】效验有效参数的合法性(相当于安检系统) @Service 【服务】业务组装(客服中心) @Repository 【数据持久层】实际业务处理(实际办理的业务) @Component 【组件】工具类层(基础的工具) @Configuration 【配置层】配置 上面四个注解功能是一样的,都可以用来创建bean实例 2.注入,装配 (1)@Autowired: 根据属性类型进行自动装配,默认按类型装配(byType)自动装配 作用于:标注 引用类型的构造器,方法,方法参数,注解 (2)@Resource: 可以根据类型注入,可以根据名称注入(byName),标注 类,字段,方法: (3)@Qualifier: 根据名称进行注入,这个@Qualifier注解的使用,和上面@Autowired一起使用, 如果有多个类型一样的Bean候选者,则需要限定其中一个候选者 (4)@Value:注入普通类型属性 注解在属性上,单个注入 支持 SpEL 从配置文件读取值 @Value("${property}") @Value("${property:默认值}")SpEL @Value(“#{SpEL表达式}”) @ConfigurationProperties 通过指定的前缀,绑定配置文件中的配置 可以注解在类上,也可以放在@Bean的方法上。批量注入配置文件中的属性 一般用于多个数据源的配置,读写分离 @PropertySource 加载指定的配置文件 @ImportResource 标注在一个配置类,导入Spring的配置文件让其生效 Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别。 需要用@ImportResource加载生效 3.完全注解开发 创建配置类,替代xml配置文件 @Configuration : 作为配置类,替代xml配置文件 @ComponentScan(basePackages = {“包名”}): 开启注解扫描 4.在增强类上面添加注解 @Aspect,可与@Component注解一起使用生成代理对象 5.AOP相关 在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置 (1)@Before:表示作为前置通知 (2)@After:最终通知 (3)@AfterReturning:后置通知(返回通知) (4)@AfterThrowing:异常通知 (5)@Around:环绕通知 (6)@Pointcut:用于相同的切入点抽取 6.bean的生命周期 @Scope("作用域")作用范围设置 @PostConstruct初始化 Java自己的注解 @PreDestroy销毁 7.SpringMVC @Component的衍生注解 @Controller 标注类 : 对应 Spring MVC 控制层Controller对象,主要用于接受用户请求并调用 Service 层返回数据给前端页面。

年龄迁移:基于扩散模型的容颜变化,从少年到老年全覆盖

文源 新智元 编辑:LRS 【新智元导读】只需几张图像,用文本即可生成任意年龄图像,用户反馈准确率达80%! 当下的「人脸识别系统」抗衰老能力非常弱,人物面部老化会显著降低识别性能,隔一段时间就需要更换人脸数据。 提升人脸识别系统的鲁棒性需要收集个体老化的高质量数据,不过近几年发布的数据集规模通常较小,年限也不够长(如5年左右),或是在姿态、照明、背景等方面有较大变化,没有专注于人脸数据。 最近,纽约大学的研究人员提出了一种通过隐扩散模型保留不同年龄身份特征的方法,并且只需要少样本训练,即可直观地用「文本提示」来控制模型输出。 论文链接:https://arxiv.org/pdf/2307.08585.pdf 研究人员引入了两个关键的组件:一个身份保持损失,以及一个小的(图像,描述)正则化集合来解决现有的基于GAN的方法所带来的限制。 在两个基准数据集CeleA和AgeDB的评估中,在常用的生物特征忠诚度(biometric fidelity)指标上,该方法比最先进的基线模型在错误不匹配率上降低了约44% 追踪人脸的年龄变化 DreamBooth 文中提出的方法基于潜扩散模型DreamBooth,其可以通过对文生图扩散模型微调的方式将单个主体放置在其他上下文(re-contextualization)中。 Dreambooth的输入要求为目标主体多张图像,以及包含主体的唯一标识符和类标签(class label)的文本提示,其中类标签是多个实例的集合表示,主体对应于属于该类的特定示例。 Dreambooth的目标是将唯一标识符与每个主体(类的特定实例)相关联,然后在文本提示的指导下,在不同的上下文中重新创建同一主体的图像。 类标签需要利用指定类别预训练扩散框架的先验知识,如果类别标签不正确或丢失可能会导致输出质量下降,唯一token充当对特定主题的引用,并且需要足够少见以避免与其他常用概念冲突。 原文作者使用了一组少于3个Unicode字符序列作为token,并用T5-XXL作为分词器。 DreamBooth使用类别先验保存损失(class-specific prior preservation loss)来增加生成图像的可变性,同时确保目标对象和输出图像之间的偏差最小,原始训练损失如下: DreamBooth在先验保存的帮助下可以有效地合成狗、猫、卡通等主体图像,不过这篇论文中主要关注的是结构更复杂、纹理也偏细节的人脸图像。 虽然类标签「person」可以捕获类似人类的特征,但这可能不足以捕获因个体差异而形成的身份特征。 所以研究人员在损失函数中引入了一个身份保存(identity-preserving)项,可以最小化原始图像和生成图像生物特征之间的距离,并用新的损失函数微调VAE。 公式中的第三项代表被拍摄物体的真实图像和生成图像之间生物特征距离,其中B代表两张图像的L1距离,相同的图像距离接近0,值越大代表两个主体的差异越大,使用预训练VGGFace作为特征抽取器。 下一步是针对特定目标进行微调,使用冻结的VAE和文本编码器,同时保持U-Net模型解冻。 UNet对VAE的编码器产生的潜在表征进行去噪,使用身份保持对比损失进行训练。 研究人员采用SimCLR框架,使用正负样本对之间的归一化温标交叉熵损失(temperature-scaled cross-entropy loss)来增强潜在表征,即下式中的S函数。 在加权项λs=0.1且温度值=0.5的情况下,计算无噪声输入(z0)和去噪声输出(zt)的潜在表征之间的对比损失。 U-Net架构中潜在表征之间的对比损失使得模型能够微调不同主体的扩散模型。 除了定制损失外,研究人员还使用正则化集将面部年龄发展(progression)和回归(regression)的概念赋给潜在扩散模型,其中正则化集合包括一个类别中所有代表性的图像,在本例中为person. 如果目标是生成真实的人脸图像,那从互联网上选择人脸图像的正则化集就足够了。 不过本文中的任务是让模型学习衰老和返老还童的概念,并且还要应用到不同的个体上,所以研究人员选择使用不同年龄组的人脸图像,然后将其与一个单词描述(one-word caption)进行配对。 图像描述对应于六个年龄组 :儿童(child)、青少年(tennager)、年轻人(youngadults)、中年人(middleaged)、中老年人(elderly)、老年人(old )。 相比数字提示(20岁、40岁),年龄描述的性能更好,并且可以在推理中用文本来提示扩散模型((photo of a ⟨ token ⟩ ⟨ class label ⟩ as ⟨ age group ⟩) 实验结果 实验设置 研究人员使用Stable Diffusion v1.4实现的DreamBooth进行实验,使用CLIP文本编码器(在laion-aesthetics v2 5+上训练)和矢量量化VAE来完成年龄变化,在训练扩散模型时,文本编码器保持冻结状态。 研究人员使用来自CelebA数据集100名受试者的2258张人脸图像和来自AgeDB数据集100名受试者的659张图像构成训练集。 除了二元属性「Young」之外,CelebA数据集没有受试者的年龄信息;AgeDB数据集包含精确年龄值,研究人员选择图像数量最多的年龄组,并将其用作训练集,其余图像则用于测试集(共2369幅图像)。 研究人员使用(图像,描述)数据对作为正则化集,其中每个人脸图像与指示其相应年龄标签的标题相关联,具体儿童<15岁、青少年15-30岁、年轻人30-40岁、中年人40-50岁、中老年人50-65岁、老年人>65岁,使用四个稀少token作为标记:wzx, sks, ams, ukj

Python语言使用PyScript开发Web应用程序

在不断发展的Web开发领域中,集成多种编程语言已经成为创新的标志。Python以其多功能性和易用性而闻名,已经超越了传统领域,进入了Web开发的领域。想象一下,Python的强大与HTML的动态性能够无缝融合,为您的Web项目提供交互功能和动态内容。 本文探讨了在HTML中运行Python代码的有趣概念,揭示了它所具有的潜力,并指导您完成实现这种融合的步骤。无论您是一位经验丰富的开发者,想要增强技能,还是一位对可能性感到好奇的新手,都请加入我们,探索Python在HTML中的集成,发现这种融合如何革新我们创建Web应用程序的方式。 PyScript 是一个框架,允许用户在浏览器中使用HTML的界面和Pyodide、WASM以及现代Web技术创建丰富的Python应用程序。它是由Anaconda于2022年的PyCon US上宣布的,Anaconda是科学计算的Python发行版的制造商。 PyScript的工作原理是将Python代码编译为WebAssembly,这是一种可以在浏览器中运行的低级语言。这意味着PyScript代码可以直接在浏览器中执行,无需服务器或JavaScript解释器。上面的图片是PyScript工作原理的基本骨架可视化。 PyScript提供了许多功能,使其成为创建Web应用程序的强大工具。这些功能包括: 完全访问Python标准库: PyScript为您提供了对Python标准库的完全访问权限,包括NumPy、Pandas和SciPy等模块。这使得在Python中创建复杂且数据密集型的Web应用程序成为可能。易于学习和使用: PyScript的设计目标是易于学习和使用,即使对于初学者也是如此。语法与普通Python非常相似,无需复杂的构建或部署步骤。与现有Web技术兼容: PyScript与现有的Web技术(如HTML、CSS和JavaScript)兼容。这意味着您可以使用PyScript创建外观和感觉与其他Web应用程序相同的Web应用程序。 好了,让我们开始吧,就像在任何编程冒险中一样 - 通过说出“Hello, World!”来开始。但请保持警惕,因为这一次,我们将以PyScript的魔法方式进行! 基本的HTML结构 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>PyScript | 你好,世界!</title> </head> <body> </body> </html> 链接PyScript文件 只需添加下面的两行,我们就可以使用PyScript了。 <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" /> <script defer src="https://pyscript.net/latest/pyscript.js"></script> 打印“你好,世界!”并显示IP地址 你好,世界! <br> 主机名和IP地址: <py-script> import socket hostname = socket.gethostname() display(hostname) ip_address = socket.gethostbyname(hostname) display(ip_address) </py-script> 在<body>标签内,输入上面的代码。以下是解释: 你好,世界! <br>:这行HTML代码显示文本“你好,世界!”然后包含了一个<br>标签。<br>标签是HTML的换行元素,在文本“你好,世界!”之后创建一个新行。 主机名和IP地址::这是纯文本,跟随<br>标签创建的换行,它只是一个标签,指示接下来的内容将显示主机名和IP地址。 在<py-script>标签内: import socket:这段Python代码导入了socket模块,该模块提供了各种网络功能,包括主机名和IP地址。hostname = socket.gethostname():此行使用socket.gethostname()函数检索当前主机的标准主机名,并将其分配给变量hostname。display(hostname):这将主机名显示给用户。ip_address = socket.gethostbyname(hostname):此行使用socket.gethostbyname()函数解析与先前获取的主机名关联的IP地址,然后将IP地址分配给变量ip_address。display(ip_address):它在浏览器中显示IP地址。 这就是全部,一旦运行HTML文件,您将能够看到类似下面显示的结果:

服务器给前端实时推送数据轻量化解决方案eventSource+Springboot

一、前端代码 body代码 <div id="result"></div> js代码 $(function(){ if(typeof(EventSource) != "undefined") { var source = new EventSource("/demo/getTime"); source.onmessage = function(event) { console.log(event.data); $("#result").html(event.data); }; source.addEventListener('error', function (event) { console.log("错误:" + event); }); source.addEventListener('open', function (event) { console.log("建立连接:" + event); }); } else { document.getElementById("result").innerHTML="抱歉,你的浏览器不支持 server-sent 事件..."; } }) 二、后端代码 WebFlux 框架依赖jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> 控制器代码 @GetMapping(value = "/getTime",produces="text/event-stream;charset=UTF-8") @ApiOperationSupport(order = 1) @ApiOperation(value = "详情", notes = "传入name") public Flux<String> getTime() { return Flux.

百度,点燃AI原生时代的引线

图片|Photo by iStok ©自象限原创 作者|程心 编辑|周游 穿梭在百度创业大赛的展区,时间好像又回到了2015年,那个“大众创业,万众创新”的时候。 当时,人人探索互联网的边界,思考互联网还能“+”什么,地产、金融、医疗...所有人都“拿着锤子找钉子”。此后的5年,互联网在千行百业的毛细血管中蔓延,成就了今天。 8年之后,大模型的火爆再次将“创业大赛”带入大众语境,9月5日,百度举办文心杯创业大赛,也是首个围绕着大模型的创业大赛,参赛的近1000个项目,覆盖了生产力工具、营销、文娱、社交、电商等领域的大量AI原生应用。 只是与8年前大家思考“互联网+”不同,今天大家思考的是“AI+”。 在Demo Day现场,「自象限」盘旋在32个投资项目展台前,创业者们意气风发,风投、大厂战投、合作方、媒体人络绎不绝。许多投资人排队“扫货”,一些因为出差没能赶到现场的投资人,从场外向「自象限」发来微信,只为求一个项目路演的名单。 ▲ 百度文心杯创业大赛现场 热闹的背后,是中国大模型来到了一个发展的新节点。国产大模型从无到有,从有到多,从多到精,如今,大模型的能力开始蔓延到千行百业,向内生长。 至此,或许一个属于AI 原生的时代,才算真正开启。 “移动互联网时代,操作系统只有安卓和iOS,而特别成功的应用有很多。只有在大模型的基础之上,产生了足够多的AI原生应用,才是一个健康的生态环境。”李彦宏讲道。 不止百度,纵观国内外,每个人都在期待AI原生应用真正落地,但究竟何为AI原生?如何打造?大模型厂商在中间扮演着怎样的角色?如何构建中国的大模型产业链? 这些待解答问题的背后,藏着新时代的启动键。 AI原生应用,落地分几步? 纵观此次大赛,参赛项目主要聚焦大模型应用层落地,占比超过8成,To C和To B应用基本各占半壁江山;同时行业分布多元,不仅有生产力工具、营销、文娱、社交、电商等AI原生应用,也涵盖医疗、HR、教育、金融、法律等垂类应用的重构与改造。 ▲ 大赛路演项目名单,自象限现场拍摄 相比于此前「自象限」参加过的多场路演,一个最大的感受是这些项目不只停留在PPT阶段,而是具体的产品已经落地能够进行现场演示,甚至有些项目的商业模型已经出现。 路演现场,共有32个项目进行了Demo展示,15个项目进入了决赛圈,我们将决赛的15家项目进行了盘点和梳理,试图找到一些未来的检索和指引。 ▲ 图为自象限根据公开资料梳理 我们发现,这些项目的逻辑并不是老产品的粗暴改造的“+AI”,而是真正做了“AI+”,也就是李彦宏强调的AI原生。 那么何为AI原生?李彦宏认为,“AI原生至少满足三个条件:第一,能用自然语言交互,这是最根本的变化;第二,能充分利用理解、生成、推理、记忆等等,这些过去技术上不具备的能力,才是AI原生应用应该去利用的;第三,每个应用的交互都不超过两级菜单,所以交互才会简单。” 按图索骥,参考此前从PC端进化到移动端的经验,核心的变化在于交互方式的改变,一是人与硬件的交互方式从点击到“滑”,更加快捷;二是人与人、人与商家的交互方式,从打电话到随时随地的可视化。 比如国外以Midjourney、Stable Diffusion为代表的文生图应用迎来了爆火,但具体能够在什么样的场景下用起来?Nolibox和Genie AI提供了两个不同的方向,前者帮助商家降本,后者则让用户通过AI释放创作力。 「Nolibox」聚焦于目前文生图最火热的电商赛道,为电商用户提供从创意设计到智能排版的一系列工具包,比如一个普通的淘宝店家,依然要请专业的设计师来设计店铺首页、详情页等页面,而「Nolibox」利用AIGC生成后,能够在实际的生产环节中起到提效作用,做到降本。 「Genie AI」则是通过AI工具让普通人也具备漫画创作的能力,主要针对二次元二创的场景,基于大模型关键词生成漫画作品。如果了解二次元的用户,一定也常常有续写或者改写漫画的冲动,但普通人并不具备漫画创作的能力,在这样具体的场景下,文生图有了着陆点。 另外2B项目也比想象的更多也更丰富。互联网时代从C端应用卷向B端,产业数字化固然是深水区也有更大的潜力。吸取了经验教训的创业者,大模型应用比之前更关注B端机会,有更多人愿意埋头做技术、做服务。 作为前15强中,聚焦AI Infra的厂商,「Vanus AI」是面向大模型的中间件服务商,通过数据管道产品实时采集客户已有的数据。将 SaaS软件、数据库、云服务等数据中的企业专有数据变成知识,再通过 embeding 构建向量知识库。在知识库和大模型的基础上,公司可以构建业务洞察、智能客服、政策解读、投研助手等AI应用。 ▲ Vanus AI项目路演 简单来说,Vanus AI的核心在于帮助企业构建行业知识库,用好大模型。企业用户可以在几分钟之内,构建起一个专属客服,并能够直接将专属客服部署在IM软件和SaaS软件中。 相比于C端“近在咫尺”的变现机会,Vanus AI CEO 历启鹏认为尽管企业服务是一条非常漫长的道路,但却具有不可替代的核心竞争力。“2B不是单纯的技术领先,而是要有经验,我们已经积累了电力巡检、制造业、销售客服等宝贵的行业经验,未来也会持续和各行业的客户合作,构建产品壁垒。”历启鹏对「自象限」讲道。 数据不会骗人,2023年3月份产品上线后,已经连续5个月用户增长超过100%,目前Vanus AI在全球多地拥有企业级客户,包括创业公司、传统企业、互联网企业等类型。 当被问到为何选择在中间件这样底层的基础软件进行创业时,历启鹏回答道:“我们团队有多年的企业服务经验,他们有来自阿里云、Oracle、Forrester 等各个不同领域的技术专家,从事近10年的中间件开发,自然更有经验。” 而这也体现了一个更重要的趋势:如今的AI原生应用创业,不止需要技术能力,还有行业能力,其中大部分创业团队都兼顾了技术经验和行业经验,才能做出一个真正能用得上的好产品。 除了VanusAI,ChatPPT CEO 周泽安拥有着近十年的企业服务经验,基于对办公场景十年的PPT引擎和功能创新经验,更了解职场人对高质量模版的大量需求以及需要降低模版的使用门槛,也正是通过一个细分场景、细分需求的持续深耕,打造出了壁垒和竞争力。据了解,过往产品口袋动画和Docer(稻壳)被WPS收购并实现了商业化运营。 ▲ 大赛路演项目ChatPPT运营数据 事实也证明了,只有这样的产品才能被市场认可。据其创始人路演中讲道,目前ChatPPT产品用户量正在指数级增长,注册用户量近72万,付费平均客单价约146元,产生商业总流水近1300多万人民币。 同样,天平知行创始团队均是法律方面的相关专家,拥有着超过10年甚至20年的法律从业经验,其CEO任中国信息协会法律分会会长。 和具体的场景结合,是应用落地的着陆点,一手抓技术一手抓行业的综合性团队,才能最终做出好的产品。这同时也意味着,AI技术不是只做表面功夫,而是已经渗透进了千行百业,从内开始升级,由内向外生长。 应用爆发的内因 相信很多人也有同样的疑问,为什么在这个节点上,应用开始大规模爆发?

浅谈Spring

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。 一、什么是IOC? IoC = Inversion of Control 翻译成中⽂是“控制反转”的意思,也就是说 Spring 是⼀个“控制反转”的容器。 1.1控制反转推导 这个控制反转怎么理解呢?我们来推导一下这个过程: 我们现在构建⼀辆“⻋”的程序,我们的实现思路和代码实现是这样的: 轮胎的尺⼨的固定的,然⽽随着对的⻋的需求量越来越⼤,个性化需求也会越来越多,这时候我们就需要加⼯多种尺⼨的轮胎,那这个时候就要对上面的程序进⾏修改了,修改后的代码如下所示: 从上面的代码中可以看出传统写法的缺陷:代码耦合性太高。 那上述问题我们可以怎么解决呢? 这就好⽐我们打造⼀辆完整的汽车,传统的方式是所有的配件都是⾃⼰造,那么当客户需求发⽣改变的时候,⽐如轮胎的尺⼨不再是原来的尺⼨了,那我们要⾃⼰动⼿来改了,但如果我们是把轮胎外包出去,那么即使是轮胎的尺⼨发⽣变变了,我们只需要向代理⼯⼚下订单就⾏了,我们⾃身是不需要出⼒的。 所以:我们可以尝试不在每个类中自己创建下级类,如果⾃⼰创建下级类就会出现当下级类发⽣改变操作,⾃⼰也要跟着修改。 此时,我们只需要将原来由自己创建的下级类,改为传递的方式(也就是注入的方式),因为我们不需要在当前类中创建下级类了,所以下级类即使发生变化(创建或减少参数),当前类本身也⽆需修改任何代码,这样就完成了程序的解耦。 代码实现思路如下: 总结对比一下: 执行顺序: 在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire 改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car 通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实 现思想。 上述过程不知道各位小伙伴能不能理解,但总结来说就是传统的写法所有的东西都是由程序去控制创建的,改进后的写法是由调用者自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口 .。 这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低 . 这也就是IOC的原型 。 1.2、IOC的本质: 控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

如何在 Next.js 中快速集成 @microsoft/signalr

如何在 Next.js 中快速集成 @microsoft/signalr 虽然只有少数项目需要集成 WebSockets 来在界面发生变化时实时响应而不重新获取数据,但这些项目仍然数量庞大。 这是一项必不可少的工作,我们不会讨论它们或者比较提供更好开发体验的第三方库。 我的目标是展示如何快速集成 @microsoft/signalr 到 Next.js 中,以及在开发过程中遇到的问题如何解决。 首先,我希望每个人都已经在本地安装和部署了 Next.js 项目。在我的案例中,版本是 13.2.4。让我们添加一些重要的库:swr(版本 2.1.5)用于数据获取以及与本地缓存进一步工作,以及 @microsoft/signalr(版本 7.0.5) - 用于 WebSockets 的 API。 npm install --save @microsoft/signalr swr 让我们从创建一个简单的 fetcher 函数和一个名为 useChatData 的新 hook 开始,以从我们的 REST API 获取初始数据。它返回了聊天消息列表、检测错误和加载状态的字段,以及允许更改缓存数据的 mutate 方法。 // hooks/useChatData.ts import useSWR from 'swr'; type Message = { content: string; createdAt: Date; id: string; }; async function fetcher<TResponse>(url: string, config: RequestInit): Promise<TResponse> { const response = await fetch(url, config); if (!

RabbitMq消息模型-队列消息

队列消息分为2种: 基本模型(SimpleQueue)、工作模型(WorkQueue) 队列消息特点: 消息不会丢失 并且 有先进先出的顺序。消息接收是有顺序的,不是随机的,仅有一个消费者能拿到数据,而且不同消费者拿不到同一份数据。 基本模型: SimpleQueue 在上图的模型中,有以下几个概念: P:为生产者,也就是要发送消息的程序C:为消费者:消息的接受者,会一直等待消息到来。queue:为消息队列,为上图中间红色部分。类似为一个邮箱,可以缓存消息,生产者向其中投递消息,消费者从其中取出消息。 适用场景:基本模型适用于 消息存取 数量不多,频率不高。 工作模型: WorkQueue WorkQueue简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息。 弊端: 当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,无法及时处理。那么这时就可以用WorkQueue模型,多个消费者共同处理消息,处理消息的速度就能大大提高了。 工作模型它默认分配模式是 平均分配给每个消费者,并没有考虑到消费者的处理能力。这样显然是有问题的。有的消费者性能高,有的消费者性能低。如果两个消费者都消费同样的消息,那么就会造成一个消费的快些一个消费的慢些,因为性能高的消费者它的消费能力要强些,性能低的消费者消费能力要弱些。 当然默认的平均分配模式也可以在消费者的配置文件中更改为能者多劳模式,能力强的多干点,能力弱的少干点。 适用场景:工作模型适用于 消息存取 数量多,频率高。

JavaScript删除树形结构中的某个属性

删除树形结构中的某个属性 arr为需处理的数组 key为要删除的属性名 const handler = (arr, key) => { if (arr) { arr.forEach((item) => { if(item[key]){ delete item[key] } if (item.children && item.children!==[]) handler(item.children, key) }) return arr } }

Vue的生命周期详解(简单易懂)

一、定义 Vue的生命周期就是实例从创建到销毁的一个过程,即从创建、初始化数据、编译模板、挂载Dom->渲染、更新->渲染,卸载等一系列的过程。 写代码时注意: Vue的生命周期钩子函数会自动绑定this上下文到实例中,这意味着不能使用箭头函数来定义一个生命周期方法(例如不能这样写:created:()=>this.fetchData()),因为箭头函数的this指向的是定义它的函数,谁定义它,它就在谁的作用域里生效。 二、Vue的生命周期分为八个阶段 分别是beforeCreate(创建前)、created(创建后)、beforeMount(挂载前)、mounted(挂载后)、beforeUpdate(更新前)、updated(更新后)、beforeDestroy(销毁前)、destroyed(销毁后)。 (1)beforeCreate 在实例初始化(new Vue())后执行,此时的数据监听和事件绑定机制都未完成,获取不到DOM节点。(可以在此阶段加loading事件,在加载实例时触发) (2)created 这个阶段vue实例已经创建,以下内容已被配置完毕:数据侦听、计算属性、方法、事件/侦听器的回调函数。但挂载阶段还没开始,仍然获取不到DOM元素。(在此阶段,初始化完成时的事件写在这里,如在这结束loading事件,也可以进行异步请求) (3)beforeMount 在这个阶段完成了DOM的初始化,但仍然无法获取到具体的DOM元素,因为vue还没有进行根节点挂载,但是根节点已经创建完成,下面Vue对DOM的操作将围绕这个根节点进行。(beforeMount这个阶段是过渡性的,在项目中使用得比较少) (4)mounted 在这个阶段,实例已经被挂载完成了,也就是能获取到数据和DOM元素了。 (注意 mounted 不会保证所有的子组件也都被挂载完成。如果你希望等到整个视图都渲染完毕再执行某些操作,可以在 mounted 内部使用 vm.$nextTick.) mounted: function () { this.$nextTick(function () { // 仅在整个视图都被渲染之后才会运行的代码 }) } (5)beforeUpdate 在数据发生改变,但页面还没有完成更新时执行的操作,在此阶段视图的数据和DOM元素的数据没有保持同步。(这里适合在现有 DOM 将要被更新之前访问它,比如移除手动添加的事件监听器) (6)updated 这个时候数据发生了改变,并且视图页面也已经完成了更新,因此,该阶段看到的DOM元素的内容是最新内容。 (注意updated 不会保证所有的子组件也都被重新渲染完毕。如果你希望等到整个视图都渲染完毕,可以在 updated 里使用 vm.$nextTick) (7)beforeDestroy 此阶段Vue实例仍然完全可用,也就是还能访问到页面的响应式数据和事件。(可以在这里注销eventBus等事件) (8)destroyed DOM元素被销毁,此时对应 的Vue 实例所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。 在Vue实例的创建过程中,DOM元素是在Mounted这个阶段才被访问到的。