首页 文章 精选 留言 我的

精选列表

搜索[基础搭建],共10000篇文章
优秀的个人博客,低调大师

基础创建自属微信公众号问答机器人

不可否认,在即将进入人工智能”对话式商务”的时代,若要运营好微信,为自已的公司、自已的店铺、自已的专业领域与兴趣爱好...建立公众号智能问答机器人是有必要性的,小信子中文理解 API 云端服务平台特别为广大非程序员的微信用户提供一个快捷通道,让您透过流程设定即刻拥有自属微信公众号问答机器人。 小信子公众号问答机器人托管流程如下图所示: 本创建指南在描述从 [ 阿里云订购 ] 到 [ 建立公众号<->阿里云关联 ] 的操作流程。 准备工作: 请先申请 微信公众平台个人帐号(个人或公司均可) 请先申请 阿里云帐号 创建流程开始: #本文结尾提供完整影片教学 1、登陆阿里云官网: https://www.aliyun.com 2、进入购买【小信子公众号问答机器人】服务 (https://market.aliyun.com/products/56928004/cmapi015641.html) 3、支付购买成功后,进入〔管理控制台〕 4、打开”记事本” 拷贝+贴上 记下 AppCode,后台进入 [公众号问答机器人管理页] 设置后会用到。 5、进入阿里云网关 https://apigateway.console.aliyun.com, 点击〔调用API〕→[应用管理] → 选择[云市场xxxxxxxx] 6、”记事本” 拷贝+贴上 记下 应用ID,后台 [公众号问答机器人管理页] 账号登录会用到, 点击 小信子微信机器人设置 的 【 调试 API】 7、进入【调试API】功能页面 输入相应的管理者邮箱帐号、密码...后,按【发送请求】,看到上面正确返回信息就可以了。”记事本” 拷贝+贴上 记下 管理者邮箱和密码。 8、打开【公众号问答机器人管理主页】https://www.aixxz.com/we.index.php ”记事本” 拷贝+贴上 应用ID、管理者邮箱和密码 登陆管理后台。 9、登陆后,显示如下页面。点击【微信公众号授权】 10、此时弹出公众平台帐号授权界面 11、拿起手机,打开微信扫描二维码,成功扫描后,会显示管理者相应的公众号列表, 选择你要授权的公众号后,会弹出以下确认画面: 12、按【授权】后,该公众号授权就完成了: 13、等待管理后台自动刷新界面,显示【已授权】,则表示授权已成功。如发现授权后返回依然显示 未授权, 请到公众号管理中,取消小信子公众号第三方授权后,再到这边重权授权一次。授权成功后, ”记事本” 拷贝+贴上 阿里云 AppCode, 给自已的机器人取个名字,填上订阅户初次关注欢迎词, 按【编辑应用】,即完成 授权。 14、测试公众号是否已授权给小信子?可输入你好或今天天气怎样的问句, 如有正确回应,恭喜您拥有自已的机器人了!!(如果之前已关注过授权的公众号,可取消后重关注即可 ) 15、如何为自己的机器人建立问答资料库?让机器人拥有您的专业能力为订阅者服务呢? 详情请看:如何使用小信子问答系统创建自属专业问答知识库 16、(新增服务)如何看到机器人与订阅户的对话内容? 例如下图: 此时在管理后台点击〔消息管理〕即可看到 对话内容,如此即可随时了解用户使用状况并增修问答知识库内容了! 应用实例: 冬瓜摄影智能问答机器人提供您想知道的摄影知识 ! 意外星座智能问答机器人随时回答您想知道的星座秘事! 完整影片教学: http://www.iqiyi.com/w_19rtyj92ed.html (可设置 1080P清晰观看) 核心理论教程:汉字基因十节课 官网:www.xiaoxinzi.com 论坛:bbs.aixxz.com

优秀的个人博客,低调大师

Java标准输入输出+基础理论+基本数据类型总结

学Java两个多月了,准备写Java相关知识,多总结(毕竟自己也是小白),以后定期写Java相关博客,一直把Java大致体系学完。只是为了自己方便查阅,有不足可指出。 1、标准输出: publicclassHelloJava{ publicstaticvoidmain(String[]args){ System.out.println("renzhiyuan学习Java"); } } 1.1)参数: public:表示的这个程序的访问权限,表示的是任何的场合可以被引用,这样java虚拟机就可以找到。main()方法,从而来运行javac程序。 static:表明方法是静态的,不依赖类的对象的,是属于类的,在类加载的时候main()方法也随着加载到内存中去。 void:main()方法是不需要返回值。 main:此方法是程序执行的入口。 String[] args:从控制台接收参数。 System.out.println:标准输出流(支持文件的输出) #System.out.println();标准错误输出流 1.2)两个输出流的区别区别: 标准错误流不支持定向输出,只能立即输出。 标准输出流支持定向输出 eg:java HelloJava>>test.txt(非追加>) 1.3)常用转义字符: //println和print区别是println会换行 // 常用的转义字符 \\ 反斜杠 \' 单引号' \" 双引号" \b 倒退一个字符 \n 回车换行 \t 跳格(一个Tab键) 1.4)程序解释: A:Java程序的最基本单位是类,所以我们要定义一个类。 格式:class 类名 举例:class HelloWorld B:在类中写内容的时候,用大括号括起来。 C:Java程序要想执行,必须有main方法。 格式:public static void main(String[] args) D:要指向那些东西呢,也用大括号括起来。 E:你要做什么呢?今天我们仅仅做了一个简单的输出 格式:System.out.println("HelloWorld"); 注意:""里面的内容是可以改动的。 (2)Java程序的开发执行流程: A:编写java源程序(.java) B:通过javac命令编译生成.class文件 C:通过java命令运行.class文件 2、键盘录入: 2.1)案例 importjava.util.Scanner; publicclassJavaTest { publicstaticvoidmain(String[]args) { Scannerscanner=newScanner(System.in); System.out.println("你的名字是什么?"); Stringname=scanner.next(); System.out.println("你家住在哪里?"); Stringaddress=scanner.next(); System.out.println("我的名字也叫"+name+address+"很高兴认识你!"); } } 2.2)实现流程: A:导包 import java.util.Scanner; 位置:在class的上边 B:创建对象 Scanner sc = new Scanner(System.in); C:获取数据 3、方法: 3.1)方法:就是完成特定功能的代码块。 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法。 3.2)格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...) { 方法体语句; return 返回值; } 修饰符:目前就用 public static。后面再详细讲解其他修饰符 返回值类型:就是功能结果的数据类型 方法名:就是起了一个名字,方便我们调用该方法。 参数类型:就是参数的数据类型 参数名:就是变量 参数分类: 实参:实际参与运算的数据 形参:方法上定义的,用于接收实际参数的变量 方法体语句:就是完成功能的代码块 return:结束方法 返回值:就是功能的结果,由return带给调用者。 3.3)两个明确: 返回值类型:结果的数据类型 参数列表:参数的个数及对应的数据类型 3.4)方法调用 A:有明确返回值的方法 a:单独调用,没有意义 b:输出调用,不是很好,因为我可能需要不结果进行进一步的操作。但是讲课一般我就用了。 c:赋值调用,推荐方案 B:void类型修饰的方法 a:单独调用 3.5)方法的注意事项 A:方法不调用不执行 B:方法之间是平级关系,不能嵌套定义 C:方法定义的时候,参数是用,隔开的 D:方法在调用的时候,不用在传递数据类型 E:如果方法有明确的返回值类型,就必须有return语句返回。 3.6)方法重载 在同一个类中,方法名相同,参数列表不同。与返回值无关。 参数列表不同: 参数的个数不同。 参数的对应的数据类型不同。 3.7)方法重载案例 不同的类型的多个同名方法的比较。 4、关键字 4.1)被Java语言赋予特定含义的单词 4.2)特点: 全部小写。 4.3)注意事项: A:goto和const作为保留字存在。 B:类似于Notepad++这样的高级记事本会对关键字有特殊颜色标记 5、标识符 4.1)就是给类,接口,方法,变量等起名字的字符序列 5.2)组成规则: A:英文大小写字母 B:数字 C:$和_ 5.3)注意事项: A:不能以数字开头 B:不能是java中的关键字 C:区分大小写 5.4)常见的命名规则(见名知意) A:包全部小写 单级包:小写 举例:liuyi,com 多级包:小写,并用.隔开 举例:cn.itcast,com.baidu B:类或者接口 一个单词:首字母大写 举例:Student,Demo 多个单词:每个单词首字母大写 举例:HelloWorld,StudentName C:方法或者变量 一个单词:首字母小写 举例:name,main 多个单词:从第二个单词开始,每个单词首字母大写 举例:studentAge,showAllNames() D:常量 全部大写 一个单词:大写 举例:PI 多个单词:大写,并用_隔开 举例:STUDENT_MAX_AGE 6、注释 6.1)就是对程序进行解释说明的文字 6.2)分类: A:单行注释// B:多行注释/**/ C:文档注释(后面讲) /** */ 6.3)把HelloWorld案例写了一个带注释的版本。 后面我们要写一个程序的过程。 需求: 分析: 实现: 代码体现: 6.4)注释的作用 A:解释说明程序,提高了代码的阅读性。 B:可以帮助我们调试程序。 7、常量 7.1)在程序执行的过程中,其值不发生改变的量 7.2)分类: A:字面值常量 B:自定义常量(后面讲) 7.3)字面值常量 A:字符串常量 "hello" B:整数常量12,23 C:小数常量12.345 D:字符常量'a','A','0' E:布尔常量true,false F:空常量null(后面讲) 7.4)在Java中针对整数常量提供了四种表现形式 A:二进制由0,1组成。以0b开头。 B:八进制由0,1,...7组成。以0开头。 C:十进制由0,1,...9组成。整数默认是十进制。 D:十六进制由0,1,...9,a,b,c,d,e,f(大小写均可)组成。以0x开头。 8、进制转换 8.1)其他进制到十进制 系数:就是每一个位上的数值 基数:x进制的基数就是x 权:对每一个位上的数据,从右,并且从0开始编号,对应的编号就是该数据的权。 结果:系数*基数^权次幂之和。 8.2)十进制到其他进制 除基取余,直到商为0,余数反转。 8.3)进制转换的快速转换法 A:十进制和二进制间的转换 8421码。 B:二进制到八进制,十六进制的转 9、数据类型 9.1)Java是一种强类型语言,针对每种数据都提供了对应的数据类型。 9.2)分类: A:基本数据类型:4类8种 B:引用数据类型:类,接口,数组。 9.3)基本数据类型 A:整数占用字节数(字节是计算机中最小的计量单位) byte1 -128~127 short2 -32768~32767 int 4 -2147483648~2147483647 long8 B:浮点数 float4 double8 C:字符 char2 D:布尔 boolean1 注意: 整数默认是int类型,浮点数默认是double。 长整数要加L或者l。 单精度的浮点数要加F或者f。 10、数据类型转换 10.1)boolean类型不参与转换 10.2)默认转换 A:从小到大 B:byte,short,char -- int -- long -- float -- double C:byte,short,char之间不相互转换,直接转成int类型参与运算。 10.3)强制转换 A:从大到小 B:可能会有精度的损失,一般不建议这样使用。 C:格式: 目标数据类型 变量名 = (目标数据类型) (被转换的数据); 10.4)思考题和面试题: A:下面两种方式有区别 float f1 = (float)12.345; float f2 = 12.345F; f1其实是通过一个double类型转换过来的,而f2本身就是个float类型。 B:下面的程序有问题吗,如果有,在哪里呢? byte b1 = 3; byte b2 = 4; byte b3 = b1 + b2; byte b4 = 3 + 4; C:字符参与运算 是查找ASCII里面的值 'a'97 'A'65 '0'48 System.out.println('a'); System.out.println('a' + 1); D:字符串参与运算 这里其实是字符串的连接 System.out.println("hello"+'a'+1); System.out.println('a'+1+"hello"); System.out.println("5+5="+5+5); System.out.println(5+5+"=5+5"); 11、变量 11.1)在程序的执行过程中,其值在某个范围内可以发生改变的量 11.2)变量的定义格式: A:数据类型 变量名 = 初始化值; B:数据类型 变量名; 变量名 = 初始化值; 12、运算符(掌握) 12.1)算术运算符 A:+,-,*,/,%,++,-- B:+的用法 a:加法 b:正号 c:字符串连接符 C:/和%的区别 数据做除法操作的时候,/取得是商,%取得是余数 D:++和--的用法 a:他们的作用是自增或者自减 b:使用 **单独使用 放在操作数据的前面和后面效果一样。 a++或者++a效果一样。 **参与操作使用 放在操作数的前面:先自增或者自减,再参与操作 int a = 10; int b = ++a; 放在操作数的后面:先参与操作,再自增或者自减 int a = 10; int b = a++; 12.2)赋值运算符 A:=,+=,-=,*=,/=,%=等 B:=叫做赋值运算符,也是最基本的赋值运算符 int x = 10; 把10赋值给int类型的变量x。 C:扩展的赋值运算符的特点 隐含了自动强制转换。 面试题: short s = 1; s = s + 1; short s = 1; s += 1; 请问上面的代码哪个有问题? 12.3)比较运算符 A:==,!=,>,>=,<,<= B:无论运算符两端简单还是复杂最终结果是boolean类型。 C:千万不要把==写成了= 12.4)逻辑运算符 A:&,|,^,!,&&,|| B:逻辑运算符用于连接boolean类型的式子 C:结论 &:有false则false |:有true则true ^:相同则false,不同则true。 情侣关系。 !:非true则false,非false则true &&:结果和&是一样的,只不过有短路效果。左边是false,右边不执行。 ||:结果和|是一样的,只不过有短路效果。左边是true,右边不执行。 12.5)位运算符(了解) A:^的特殊用法 一个数据针对另一个数据位异或两次,该数不变 B:面试题 a:请实现两个变量的交换 **采用第三方变量 **用位异或运算符 左边a,b,a 右边a^b b:请用最有效率的方式计算出2乘以8的结果 2<<3 12.6)三元运算符 A:格式 比较表达式?表达式1:表达式2; B:执行流程: 首先计算比较表达式的值,看是true还是false。 如果是true,表达式1就是结果。 如果是false,表达式2就是结果。 C:案例: a:比较两个数据是否相等 b:获取两个数据中的最大值 c:获取三个数据中的最大值 //获取三个整数中的最大值。 publicclassJavaTest{ publicstaticvoidmain(String[]args){ intx=10; inty=5; intz=20; System.out.println(x>y?"x大于y":"x小于y"); intx=10; inty=5; intz=(x>y?x:y); System.out.println("z:"+z); //第一种方法:先比较a、b最大值,在拿a、b最大值和c比较。 intx=10; inty=5; intz=20; inttemp=((x>y)?x:y); intmax=((temp>z)?temp:z); System.out.println("abc最大值是:"+max); //第二种方法(不推荐) intmax=(x>y)?((x>z)?x:z):((y>z)?y:z); System.out.println("abc最大值是:"+max); 获取两个整数是否相同 booleanflag=(x==y)?true:false;//不需要ture和false,因为是booleam类型。 booleanflag=(x==y); System.out.println(flag);

优秀的个人博客,低调大师

Rainbond实战:3分钟搭建一个私有笔记服务-Joplin

Joplin 是一款开源的笔记和待办事项应用程序,支持Markdown编辑和多端同步,并且可以私有化部署,对于像我这样习惯使用Markdown写作的人来说,简直是一大福音。在此之前我用过一些云笔记服务,但是随着“降本增效”,数据的安全性无法保障,因此我将注意力转向了可以私有化部署的笔记服务。 Joplin 本身是一个客户端软件,下载即用。但是如果需要多端同步,则需要部署私有化服务或者选择官方提供的 Joplin Cloud。本文将介绍如何通过 Rainbond 在 3 分钟内部署好这个私有笔记服务。 Joplin:功能全面的私有笔记服务 Joplin 是一个完全开源的笔记程序。支持 Windows、Mac、安卓、iPhone 全平台。所有笔记以开放的格式保存在本地,可以离线使用,同时还支持多种同步方式,你可以完全掌握你的数据。 Joplin 有以下优点: 代码开源,已经有接近 41k Star,稳定性有保障 支持完全离线使用,并且采用了端到端加密 支持多种同步方式,可以自建 Joplin Server、兼容各类 S3 协议的对象存储、文件系统等多种同步方式 支持从其他笔记平台导入已有笔记,如印象笔记、Markdown、OneNote等,迁移成本低 支持导出多种格式,如HTML、PDF、Markdown等 笔记支持网络分享,可以通过自建的 Joplin Server 分享给其他用户在线浏览,与其他云笔记服务一样 一键部署 Joplin 在部署时需要用到 Rainbond 这个应用管理平台,利用这个平台可以部署各类应用并且统一进行管理。当不需要使用Joplin时,还可以直接通过该平台关闭应用,减少资源占用。 安装Rainbond Rainbond 是一个开源的应用管理平台,不需要了解容器和K8s,就可以轻松部署和管理各类应用;在这里我们可以将其理解为电脑的操作系统,对于像Joplin之类的应用只需要鼠标点点,即可安装使用。 可通过一条命令快速安装 Rainbond。 curl -o install.sh https://get.rainbond.com && bash ./install.sh 通过应用商店部署Joplin Joplin 这个应用已经发布到 Rainbond 开源应用商店,用户可通过开源应用商店一键安装。在 Rainbond 的 「平台管理 -> 应用市场 -> 开源应用商店」 中搜索 Joplin 并点击安装。即可将应用运行起来。 看到如下界面,表示你的应用已经部署完成了。 配置Joplin Joplin 运行起来以后,由于它的安全设置,访问的域名必须与容器内部读取的环境变量保持一致才可正常工作。因此我们需要点击 joplin 这个绿色的六边形,访问到该软件的详情页面。 进入详情页面后,点击「端口」,查看组件当前的访问策略,如果对外服务未打开,则打开对外服务会自动生成可访问的域名。 复制该域名,切换到「环境变量」的Tab页,找到 「APP_BASE_URL」这个环境变量,修改它的值为刚刚复制的域名。修改完成后,点击右上角的「滚动(更新)」按钮,等待更新完成,即可直接访问 Joplin。 默认账户:admin@localhost 默认密码:admin 至此,已经部署好了 Joplin 这个应用,只需要登录后,根据页面提示下载客户端。下载完成后,在客户端的设置中,配置同步选项。同步目标选择 Joplin Server,URL 填写刚刚的访问域名,邮箱和密码填写上面的默认账户和密码。如下图所示: 后续在你客户端的笔记都会同步到你部署的 Joplin 中。无论是在手机还是电脑都可以随时记录和同步。 应用管理 如果不需要 Joplin 一直运行,后续可以在该软件的详情页面进行关闭。通过这个详情页面,我们可以查看 Joplin 的运行状态,运行日志,同时可以调整其运行实例数量和占用的资源大小。域名、环境变量等参数均可在此配置。

优秀的个人博客,低调大师

使用MASA全家桶从零开始搭建IoT平台(三)管理设备的连接状态

前言 获取一个设备的在线和离线状态,是一个很关键的功能。我们对设备下发的控制指令,设备处于在线状态才能及时给我们反馈。这里的在线和离线,我们可以简单的理解为设备与MQTT的连接状态。 分析 我们打电话的时候经常能听到:"您拨打的用户已关机“和”用户不在服务区或暂时无法接通“,这两种的区别是什么? 1、当用户开机时,会自动向最近的移动基站注册,基站标记该用户为"attach"(在线)状态。 2、当用户关机时,手机会发起datach流程,告知基站自己关机了,基站标记该用户为"detach"(离线)状态。这样再次拨打就可以节省寻呼资源,直接提示用户关机。 3、当用户忽然进入无网络的环境,或者手机故障,导致来不及发起datach流程,基站还认为用户"在线",当有人拨打用户号码时,基站测会对用户进行寻呼,但是超时得不到回应后,就会提示"不在服务区"或者"暂时无法接通" 的语音。 其实这个方案在IoT上也是可行的,我们可以让设备在线和离线的过程中向特定Topic发送状态消息,但是存在问题,我们需要一个单独的Broker去订阅这个Topic,但是这个单独的Broker很容易成为单点故障点。而且如果设备数量很大,这种意外离线的设备也很难及时发现,需要下发指令后等待设备响应超时才能发现。 方案1:遗嘱消息 MQTT 遗嘱消息可以在客户端意外断线时将“遗嘱”优雅地发送给第三方订阅者,以实现离线通知、设备状态更新等业务。其中意外断线指客户端断开前未向服务器发送 DISCONNECT 消息,比如: 因网络故障或网络波动,设备在保持连接周期内未能通讯,连接被服务端关闭 设备意外掉电 设备尝试进行不被允许的操作而被服务端关闭连接,例如订阅自身权限以外的主题等 遗嘱消息在 MQTT 客户端向服务器端 CONNECT 请求时设置,可选属性包括是否发送遗嘱消息 (Will Message)标志,和遗嘱消息主题 (Topic) 与内容(Payload) 以及 Properties。 值得一提的,遗嘱消息发布的时间可能会有延迟:通常意外断线时,服务器无法立即检测到断线行为,需要通过连接保活心跳机制并经过一定周期后才会触发;MQTT 5.0 提供的遗嘱延迟间隔(Will Delay Interval)属性也会影响发布时间。 演示遗嘱消息的使用 我们使用A、B两台电脑使用MQTT X来演示。 我们在A电脑的 MQTT X 中新建一个名为 Test 的连接,Host 修改为 修改为我们的MQTT地址(192.120.5.204),并输入账号密码,在 Advanced 部分选择 MQTT Version 为 5.0,并且将 Session Expiry Interval 设置为 10,确保会话不会在遗嘱消息发布前过期。 然后在 Lass Will and Testament 部分将 Last-Will Topic 设置为 offline,Last-Will Payload 设置为 I'm offline,Will Delay Interval (s) 设置为 5。 完成以上设置后,我们点击右上角的 Connect 按钮以建立连接。 我们在B电脑的MQTTX中新建一个连接Sub,mqtt地址同样指向我们的mqtt服务器(192.120.5.204) 并订阅offline主题 我们用任务管理器直接结束A电脑的MQTTX进程,这是连接会被直接断开,模拟了设备断电的场景,在5s之后,在B电脑的MQTTX订阅中收到了一条内容为 I‘m offline 的遗嘱消息。 实施流程 1、设备遗嘱消息内容设置为offline,该遗嘱主题与一个普通发送状态的主题设定成同一个 {设备名称}/status。例如 284202304230001/status 2、当设备连接时,向主题 {设备名称}/status 发送内容为 online 的Retained消息,其它客户端订阅主题 {设备名称}/status 的时候,将获取到 Retained 消息为 online。 保留消息(Retain ) MQTT 服务端收到 Retain 标志为 1 的 PUBLISH 报文时,会将该报文视为保留消息,除了被正常转发以外, 保留消息会被存储在服务端,每个主题下只能存在一份保留消息,因此如果已经存在相同主题的保留消息,则该保留消息被替换。 当客户端建立订阅时,如果服务端存在主题匹配的保留消息,则这些保留消息将被立即发送给该客户端。 借助保留消息,新的订阅者能够立即获取最近的状态,而不需要等待无法预期的时间,这在很多场景下是非常重要的。 EMQX 默认开启保留消息的能力和服务,可以在 etc/emqx.conf 中修改 mqtt.retain_available 为 false 来关闭保留消息的能力, 这样客户端将被禁止发送 Retain 标志为 1 的 PUBLISH 报文,否则,客户端将会收到原因码为 0x9A(不支持保留消息)的 DISCONNECT 报文。 保留消息的服务会存储和管理客户端发送的保留消息,并发送给相应的订阅者。 3、当客户端异常断开时,系统自动向主题 {设备名称}/status 发送内容为 offline 的消息,其它订阅了此主题的客户端会马上收到 offline 消息;如果遗嘱消息设置了 Will Retain,那么此时如果有新的订阅 A/status 主题的客户端上线,也将获取到内容为 offline 的遗嘱消息。 方案2:使用WebHook 方案1需要设备主动设置遗嘱消息才能实现,那么有没有更简单的方式,直接通过设备与Mqtt的连接事件来获取连接状态呢。 EMQX 设计了一套WebHook系统,可以通过这个自带的WebHook系统获取内部的事件并进行处理。WebHook的原理很简单,当设备与mqtt建立连接或者断开连接时,EMQX会把事件的信息通过我们的配置调用特定的URL上的接口,实现通知。 使用WebHook还可以有限避免单点故障。所以本项目会采用WebHook的方式来实现对设备在线和离线的管理。 开启WebHook 在数据集成 -> 数据桥接 中创建一个Webhook 名称设置为ConnectedEvent,URL 中填写我们的Webhook地址,也就是触发事件之后的调用接口地址,这里我们填: http://192.120.5.204:5000/api/Device/ConnectedEvent 请求方式为Post,其他内容保持默认不变 这里注意URL可以通过${field}的方式拼接,请求体也可以自己指定,如果留空会原样转发消息,我们这里请求体留空 设备在线和离线的事件转发的消息格式如下 { "username": "284202304230001", "timestamp": 1682652598840, "sockname": "172.17.0.5:1883", "receive_maximum": 32, "proto_ver": 5, "proto_name": "MQTT", "peername": "172.17.0.1:48524", "node": "emqx@172.17.0.5", "mountpoint": "undefined", "metadata": { "rule_id": "rule_3hsx" }, "keepalive": 60, "is_bridge": false, "expiry_interval": 10, "event": "client.connected", "connected_at": 1682652598840, "conn_props": { "User-Property": {}, "Session-Expiry-Interval": 10 }, "clientid": "mqttx_c4491df0", "clean_start": false } 我们点击 创建 ,并继续点击 创建规则 我们在创建规则中指定新的规则名称 rule_client_connected,并在SQL编辑器复制以下内容 SELECT * FROM "$events/client_connected", "$events/client_disconnected" 在右侧的事件中,我们可以看到所有可用的事件,我们选择了连接和断开两个事件,在这两个事件触发时会通过Webhook调用我们配置的接口,这样我们就能获取到设备的在线、离线状态了。 我们点击 创建按钮 完成规则的创建 我们可以看见我们创建好的规则 点击规则ID,还可以看到统计数据 在FLows中还可以看到整个工作流程 演示Webhook 我们使用MQTTX模拟一次设备连接和断开动作,可以在规则统计界面看到我们的操作已经被记录。 编写代码 我们这里采用方案2。 我们需要实现之前配置的ConnectedEvent接口 /// <summary> /// 连接事件请求 /// </summary> public class ConnectedEventRequest { /// <summary> /// 设备名称 /// </summary> public string Username { get; set; } /// <summary> /// 时间戳 /// </summary> public long Timestamp { get; set; } /// <summary> /// 事件(连接/断开) /// </summary> public string Event { get; set; } /// <summary> /// 连接时间(断开事件中为0) /// </summary> public long Connected_at { get; set; } /// <summary> /// Client ID /// </summary> public string Clientid { get; set; } } /// <summary> /// 更新设备在线状态 /// </summary> /// <param name="deviceName"></param> /// <param name="onlineStatus"></param> /// <returns></returns> public async Task UpdateDeviceOnlineStatusAsync(string deviceName, OnLineStates onlineStatus) { var device = await _ioTDbContext.IoTDeviceInfo.Include(o => o.IoTDeviceExtend).AsNoTracking() .FirstOrDefaultAsync(o => o.DeviceName == deviceName); if (device == null) { return; } else { if (device.IoTDeviceExtend == null) //扩展表为空 { device.IoTDeviceExtend = new IoTDeviceExtend { DeviceInfoId = device.Id, OnLineStates = (int)onlineStatus, }; _ioTDbContext.Attach(device.IoTDeviceExtend); _ioTDbContext.Entry(device.IoTDeviceExtend).State = EntityState.Added; _ioTDbContext.Entry(device.IoTDeviceExtend).Property(o => o.OnLineStates).IsModified = true; await _ioTDbContext.SaveChangesAsync(); } if (device.IoTDeviceExtend.OnLineStates != (int)onlineStatus) //在线状态不一致 { device.IoTDeviceExtend.OnLineStates = (int)onlineStatus; _ioTDbContext.Attach(device.IoTDeviceExtend); //防止更新其他字段 _ioTDbContext.Entry(device.IoTDeviceExtend).State = EntityState.Unchanged; _ioTDbContext.Entry(device.IoTDeviceExtend).Property(o => o.OnLineStates).IsModified = true; await _ioTDbContext.SaveChangesAsync(); } } } 我们根据Event中的内容来判断是 连接(client.connected)/断开(client.disconnected) 的事件 /// <summary> /// 连接、断开事件 /// </summary> /// <param name="request"></param> /// <returns></returns> [HttpPost] public async Task ConnectedEventAsync([FromBody] ConnectedEventRequest request) { var onlineStatus = request.Event switch { "client.connected" => OnLineStates.OnLine, _ => OnLineStates.OffLine }; await _deviceHandler.UpdateDeviceOnlineStatusAsync(request.Username, onlineStatus); } #总结 以上就是本文要讲的内容,我们可以通过MQTTX来测试我们的代码有效性。 该方案还存在部分缺点,例如: 1、每次设备上下线会导致频繁的请求接口,在大量设备接入的场景中需要考虑接口性能。 2、由于网络等问题,Web调用顺序可能不能完全保证,也许离线会比在线事件更早处理,从而导致状态不一致。我们后面会尝试用其他方案来替代WebHook,尝试解决上述问题,在此之前我们都会继续使用WebHook进行功能演示。 完整代码在这里:https://github.com/sunday866/MASA.IoT-Training-Demos 如果你对我们的 MASA 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们 WeChat:MasaStackTechOps QQ:7424099

优秀的个人博客,低调大师

如何搭建一台永久运行的个人服务器?试试这个黑科技!

作者:彭小呆<br> 来源:segmentfault.com/a/1190000021143144 一、树莓派是什么? Raspberry Pi(中文名为树莓派,简写为 RPi,(或者 RasPi / RPI) 是为学习计算机编程教育而设计),只有信用卡大小的微型电脑,其系统基于 Linux。随着 Windows 10 IoT 的发布,我们也将可以用上运行 Windows 的树莓派。 自问世以来,受众多计算机发烧友和创客的追捧,曾经一“派”难求。别看其外表“娇小”,内“心”却很强大,视频、音频等功能通通皆有,可谓是麻雀虽小,五脏俱全。 1. 用我的话理解 用我的话理解就是树莓派就是一台主机,你可以外接显示器,键盘鼠标,u盘等等外设,因为它体积很小,而且又有很多串口和外接的口,可以直接调用很多底层硬件。 2. 市面上的型号 市面上大多是 3 代 B+ 型,淘宝一搜树莓派一大堆都是,价钱纯主板(不要任何外设)在 230+ 左右,有点小贵,超过我的预算,所以我继续寻找廉价的,终于让我发现了一款 100+ 的树莓派。 3. 树莓派 zero w 树莓派 zero w 是一款 mini 的树莓派,体质只有 3b+ 的 1/3。实际到手后,你会发现它真的超级小,超级可爱。以下是我的实物图,你可以看看大小到底有多 mini。 你可以看到,最上面是一根普通的黑色签字笔,接下来是一个即插即用型的外接 wifi 网卡,然后是一个 USB 读卡器,最底下的就是我们今天的主角 zero w。它真的超级小,有木有。真的是完美的诠释了那句“麻雀虽小,五脏俱全”的话。 zero w 这款树莓派的主要参数如下: • BCM2835 处理器,1GHz 主频,512MB RAM • BCM43438 WiFi / BT 芯片 • micro-USB 电源接口 • micro-USB OTG 接口 • miniHDMI 端口 • 复合视频和重置扩展接口 • 脆弱的 CSI 摄像头接口 • micro-SD 卡座,存放操作系统 • 40-pin GPIO 扩展接口 • 尺寸:65mm*30mm 你别看它的 cpu 只有 1 核,内存只有 512MB,就觉得它可能什么都做不了,但是实际上它的性能还是很好的,用于跑一个网站真的是小 case。 4. 更多树莓派 关于更多树莓派型号或者使用教程你可以去树莓派实验室这个网站,上面有丰富的资源。 二、树莓派zero w安装系统 1. 准备 你可能提前需要准备的东西如下: • 16GB or 32GB 的 SanDisk 内存卡(注意是以前那种放在手机上,很小的哦) • 一根最普通不过的 usb 安卓数据线(not type-c) • u 盘格式化工具(推荐使用 SDFormatter) • 系统烧写工具(Win32DiskImager) • 树莓派系统(可以去官网下载) 我使用的是 Raspbian Stretch Lite 这个系统镜像,这个系统是官方制作的,lite 是无桌面版的,只有黑漆漆的控制台,优点是体积小,省性能和内存。 名字带有 desktop 的是有桌面 ui 的,对不熟悉 liunx 系统的朋友可能更友好,但是体积很大,占用的性能也会更高。 2. 第一步下载系统镜像 下载好你需要的系统镜像后,如下图 一开始只有一个 zip 的压缩包,大小大概 360MB 左右,你需要把它解压,得到上图的文件夹。 然后进入文件夹可以看到一个 img 的镜像,大小为 1.7GB 左右。 ps:这个官方的 Raspbian 镜像,如果是其他第三方的镜像,可能下载后的压缩包解压后不是 img 镜像,这种情况请另行百度解决。 3. 使用 Win32DiskImager 往内存卡中写入镜像 把内存卡插入读卡器后,插入电脑。 打开 Win32DiskImager 软件后,选择 img 镜像,设备选择你的 U 盘,然后点击写入就可以了,写入完成后会弹出成功的提示框。 ps: 我上图没有选择设备,因为的没插入读卡器,仅仅是示范而已 4. 修改 boot 分区的文件 先别急着拔出读卡器,此时,我们电脑可以看到 u 盘中只有一个名为 boot 的分区,大小可能只有 40MB 左右,不要着急,因为 window 不识别内存卡中 liunx 系统的其他分区。 4.1 新建 ssh 文件 因为我们的 zero w 有一个 mini hdmi 的接口,但是我不需要屏幕,所以需要使用 ssh 连接到 zero w 中的系统,所以需要在第一次开机就能开启 ssh 功能。 我们进入 boot 分区内,然后新建一个名为 ssh 的文件,注意不要后缀名!!!!也不要往里面写任何东西!! 4.2 新建 wpa_supplicant.conf 文件 因为 ssh 连接是需要 ip 地址的,所以我们需要将 zero w 在第一次开机自动连接 wifi,使其和我们的电脑处于一个局域网,这样我们才可以通过 ssh 连接到 zero w 的系统。 同样的在 boot 分区内,新建一个名为 wpa_supplicant.conf 的文件,然后往里面写入如下内容后保存: country=CN ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="你的wifi名字" psk="你的wifi密码" } 5. 组装我们的最小主机并连接 取出读卡器中的内存卡,然后插入到 zero w 中,使用一根 usb 安卓数据线连接电源(5V1A)即可。 等待几分钟,期间我们的 zero w 的指示灯会一直闪烁,很正常,等待指示灯常亮的时候,我们去路由器上,查看一下树莓派的 ip 地址。 可以看到我们 zero w 的 ip 为 192.168.0.104,然后使用 ssh 连接工具(推荐使用 putty)连接树莓派,初始账户为 pi,密码是 raspberry。 连接成功,如上图所示。这样我们的系统就正确无误的安装好了。 ps: 如果是手机开启热点当做一个路由器的话,咱们手机下载一个名叫 android terminal 的 app,然后输入 ip neigh 指令,就可以查到连接到手机的设备的 ip 信息了。 6. 优化咱们树莓派的系统 6.1 修改源 因为国外的源,咱们在国内的连接过去网速很慢,所以我们需要修改为国内的源,我修改的是中科大的源。 6.1.1 修改 sources.list 文件 sudo nano /etc/apt/sources.list --注释其他内容,添加以下: deb http://mirrors.ustc.edu.cn/raspbian/raspbian/raspbian stretch main contrib non-free rpi 6.1.2 修改 raspi.list 文件 sudo nano /etc/apt/sources.list.d/raspi.list --注释其他内容,添加以下: deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian stretch main ui 6.1.3 执行更新 sudo apt-get update sudo apt-get upgrade 6.2 修改时区 sudo dpkg-reconfigure tzdata 找到亚洲 Asia,然后选择 shanghai 就可以了。 6.3 开机自启 ssh 第一种: sudo raspi-config 进入选择找到 interfacing option 选择,然后找到 ssh,按回车使能 enable 就可以了。 第二种: 在终端命令行中启动 SSH 服务后,如果系统重启或关机后启动,SSH 服务默认是关闭的,依然需要手动启动,为了方便可以设置 SSH 服务开机自动启动,打开 /etc/rc.local 文件,在语句 exit 0 之前加入:/etc/init.d/ssh start 建议都试试,反之我的是可以了。 7. 安装 nginx #安装 sudo apt-get install nginx #启动 sudo /etc/init.d/nginx start #重启 sudo /etc/init.d/nginx restart #停止 sudo /etc/init.d/nginx stop 打开浏览器访问 192.168.0.104(你的树莓派 ip 地址),可以看到 nginx 的页面,说明安装好了。 我这边上传了我的博客,如下图 可以正常的看到页面了,但是这样只能在内网(局域网中)看到,我想让所有人都可以访问怎么办? 8. 内网穿透 内网穿透,意思就是将内网(本地)的 web 应用通过 nat 穿透到公网上,从而让别人可以访问到。 内网穿透目前主要由 ngrok 和 frp 两种,都非常好用,国内 ngrok 免费的有 ittun、sunny 和 natapp,这三个都是免费的,前面两个可以自定义域名,后面的需要 vip 版本才可以自定义域名。 我这三种都试过,我发现 sunny 的 arm 版本的 ngrok 客户端在我的树莓派运行不了,ittun 的和 natpp 的 ngrok 都可以,由于需要自定义域名,我使用的是 ittun 的 ngrok_arm 版本的。 使用方法这三者官网都有详细说明,大家自行查看。 这是正常运行时的截图,访问 http://zerow.ittun.com/ 时可以... 因为需要 ngrok 在后台运行,所以我用的是 screen 会话使其可以在后台运行。但是开启自启,还没有实现,万一断电或者断网了,我必须手动去运行一下 ngrok,这是目前没有解决的痛点。 9. 更多 树莓派不仅仅只是可以用于运行一个网站,还有很多很多的功能等待你的开发,可以多去看看树莓派实验室里面,很多大神都写了很多实用的教程。 这个zero w 状态信息如下: 在上面开启了一个 nginx 和 ngrok 服务,内存剩余还有 250MB,还是很舒服的,cpu 温度也不算高,运行两天了,基本在 37-39 之间。 近期热文推荐: 1.1,000+ 道 Java面试题及答案整理(2021最新版) 2.别在再满屏的 if/ else 了,试试策略模式,真香!! 3.卧槽!Java 中的 xx ≠ null 是什么新语法? 4.Spring Boot 2.5 重磅发布,黑暗模式太炸了! 5.《Java开发手册(嵩山版)》最新发布,速速下载! 觉得不错,别忘了随手点赞+转发哦!

优秀的个人博客,低调大师

开放原子读书会第 3 期:如何从 0-1 搭建开源社区

开放原子读书会将于2021年7月28日迎来第3期的聚会,想了解如何创建一个成功的开源社区,并让社区项目保持正常运转吗?7月28日20:00-21:30锁定开放原子读书会直播间,《社区运营的艺术》给你答案! “归属感使人们驻留在社区。这种归属感是社区建设的目标。强大社区的标志就是,它的成员们都拥有归属感。”适合本书读者:专业的社区经理,志愿者和社区领导人,商业组织,开源软件的开发者,市场营销人员,活动家。 本期内容简介 《社区运营的艺术(第2版)》的作者Jono Bacon用自己多年经验和教训试着给读者提供一些参考,包括如何建立战略规划、如何进行有效的沟通、如何创建简单易用的流程、如何运用社交媒体扩大社区的影响力等,同时分享了对知名社区领袖采访的经历,帮助读者窥探顶级社区成功的奥秘。 书籍作者介绍 Jono Bacon 是一位出色的社区经理、顾问,以及四本书的作者。现担任Ubuntu社区这一全球性社区的经理,他写的关于开源软件的博客始终是最受欢迎的博客之一,同时他创立了社区领导人峰会。 本期嘉宾介绍 开放原子读书会第3期,此次读书会主持人由开放原子教育教研总监郭晧担任,直播期间欢迎踊跃向嘉宾提问,此次读书会直播干货满满,不容错过哦~ 我们邀请了微众银行开源管理办公室负责人钟燕清、LFAPAC开源布道师马景贺及ApacheDubbo与Apollo PMC邹毅贤,3位嘉宾将共同探讨交流:如何创建一个成功的开源社区并让社区项目保持正常运转? 邀请好友一起读书还有奖品拿 丰富奖品送到手软! 邀请达人奖品送不停 (开放原子读书会第3期-邀请达人榜奖励规则图) 提前预约,一起读书!如何建立战略规划?如何进行有效的沟通?如何创建简单易用的流程?一切答案就在7月28日20:00-21:30,马上扫描下方海报二维码预约直播: 长按保存 分享立即扫码 预约直播

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册