Root


  • Home

  • About

  • Tags

  • Categories

  • Archives

nginx(一)基础内容

Posted on 2018-07-14 | In 服务器

一.基础准备内容

  1. 简要来说nginx功能:反向代理和负载均衡
  2. 轻量级的web服务器/反向代理服务器和电子邮件(IMAP/POP3)代理服务器,占用内存少,并发能力强,业界认为作为Apache2.2+mod_proxy_balancer的轻量级代替者
  3. 特点:性能较高,相应静态页面的速度很快
    分阶段资源分配技术:CPU和内存占用率很低
    热部署:nginx支持热部署,启动非常容易,可在不间断服务的情况下,对软件版本进行升级
  4. nginx:
    (1)HTTP和反向代理服务器
    (2)邮件代理服务器
    (3)TCP/UDP代理服务器

二.架构

  1. nginx启动后
    unix系统通过daemon(守护进程)方式在后台运行,也可以在生产模式中手动关闭master进程让nginx在前台运行,以多进程模式运行
  2. 进程
    以多进程的模式运行,一个master进程管理多个workder进程,master进程会接受来自外界发的信号,控制nginx,可以通过kill向master进程发送信号(老版本),不同worker进程独立且平等
  3. nginx处理请求的过程

    每一个进程都是fork自master进程
    (1)80端口的http服务时,一个连接请求过来
    (2)在master进程中先建立好需要listen的socket(listenfd),再fork出多个worker进程
    (3)所有worker进程的listenfd会在新连接到来时变得可读,(保证只有一个进程处理连接)所有worker进程在注册listenfd读事件前抢accept_mutex
    (4)抢到互斥锁的进程注册listenfd,在读事件里调用accept接受该连接
    (5)worker进程在accept连接之后,开始读取请求、解析请求、处理请求

  4. 并发处理
    每个请求会独占一个工作线程,当并发数上到几千时,就同时有几千的线程在处理请求了
    同时监测多个事件,调用他们是阻塞的,但可以设置超时时间
    在24G内存的机器上,处理的并发请求数达到过200万
    推荐使用cpu的核数为worker的个数
  5. 一个基本的web服务器来说,事件通常有三种类型,网络事件、信号、定时器
  6. 在处理网络事件的回调函数时,通过做的第一个事情就是判断超时,然后再去处理网络事件
  7. 基本概念
    (1)connection
    connection为对tcp连接的封装,包括连接的socket,读事件,写事件。nginx的http请求是建立在connection之上的
    tcp连接的生命周期
    启动nginx,解析配置文件,得到需要监听的端口和ip地址;在master进程中,初始化好监控的socket;fork进程后竞争客户端可以向nginx发起连接;客户端和服务器通过三次握手建立好一个连接,某个进程会accept成功,得到建立好连接的socket,创建nginx对连接的封装,即ngx_connection_t结构体;设置读写事件吹函数并添加读写事件来与客户端进行数据交换;nginx或者客户端来关掉连接
    nginx连接数:worker_connections*worker_processes
    nginx反向代理时,需要/2,会并发建立与客户端和后端服务的连接
    每个socket连接会占掉一个fd,nginx通过worker_connections设置每个进程支持的最大连接数。nginx通过连接池来管理,每个worker进程都有一个独立的连接池,连接池的大小为worker_connections,保存时实际为ngx_connection_t结构的数组,通过链表free_connections来保存所有空闲的ngx_connection_t
    (2)request
    nginx中指的是http请求,具体的数据结构是nginx_http_request_t,是对http请求的封装,包括请求行、请求头、请求体、响应行、响应头、响应体
    (3)keeplive
    (4)pipe
    (5)lingering_close

Ngixn基本上分为三个模块:handler、filter和upstram;handler和filter可以完成单机工作,upstram用来完成网络数据的接收、处理和转发

三.handler模块:接受来自客户端的请求并产生输出的模块

  1. Nginx启动时,每个handler模块都有一次机会把自己关联到对应的location上,多个同时关联一个location,那么只有一个handler会真正起作用
  2. handler模块处理的结果:处理成功、处理失败、拒绝处理
  3. handler中每一个模块都会提供一些配置指令,配置信息需要定义该模块的配置结构来进行存储,Nginx的配置信息分成了几个作用于(main、server、location)
  4. handler模块的挂载
    handler真正的处理函数通过两种方式挂载到过程中,按处理阶段挂载,按需挂载
    (1)按处理阶段挂载:11个阶段
    自定义的模块大多挂载在NGX_HTTP_CONTENT_PHASE阶段,挂载动作一般在模块上下文调用的postconfiguration函数中
    NGX_HTTP_POST_READ_PHASE: 读取请求内容阶段
    NGX_HTTP_SERVER_REWRITE_PHASE: Server 请求地址重写阶段
    NGX_HTTP_FIND_CONFIG_PHASE: 配置查找阶段:
    NGX_HTTP_REWRITE_PHASE: Location 请求地址重写阶段
    NGX_HTTP_POST_REWRITE_PHASE: 请求地址重写提交阶段
    NGX_HTTP_PREACCESS_PHASE: 访问权限检查准备阶段
    NGX_HTTP_ACCESS_PHASE: 访问权限检查阶段
    NGX_HTTP_POST_ACCESS_PHASE: 访问权限检查提交阶段
    NGX_HTTP_TRY_FILES_PHASE: 配置项 try_files 处理阶段
    NGX_HTTP_CONTENT_PHASE: 内容产生阶段
    NGX_HTTP_LOG_PHASE: 日志模块处理阶段

(2)按需挂载content handler
必须在NGX_HTTP_CONTENT_PHASE阶段执行
用处:某个模块对某个locaiton进行了处理后,发现符合处理的逻辑,而且也没有必要再调用NGX_HTTP_CONTENT_PHASE阶段的其他handler进行处理,就动态挂载上这个handler

  1. handler模块的编译和使用,需要在nginx的源码目录中,通过configure指令的参数进行编译

四.过滤模块filter

  1. 过滤模块
    过滤模块是过滤响应头和内容的模块,可以对回复的头和内容进行处理。处理时间在获取回复内容之后,向用户发送响应之前。
    处理过程
    分为两个阶段:过滤HTTP回复的头部和主体,分别对头部和主体进行修改
  2. nginx_chain_t结构体为单向链表,应和Nginx流式的输出模式
  3. 发出子请求,就是在过滤响应内容的时候,可以发送新的请求,Nginx会根据你调用的先后顺序,将多个回复的内容拼接成正常的响应主体
    保证父请求和子请求的顺序
    Nginx发出子请求的时候,调用ngx_http_subrequest函数,将子请求插入父请求的r -> postponed链表。子请求会在主请求执行完毕时依次调用。子请求同样会有一个请求所有的生存期和处理过程,也会进入filter模块流程

五.upstream模块

  1. 数据转发功能:具备网路应用级别的拆分、封装和整合的战略功能,是nginx有能力构建一个网络应用的关键组件
  2. upstream严格属于handler,不产生自己的内容,而是通过请求后端服务器得到内容。请求并取得响应的过程被封装到Nginx内部
  3. upstream模块接口
SN 描述
create_request 生成发送到后端服务器的请求缓冲(缓冲链),在初始化 upstream 时使用。
reinit_request 在某台后端服务器出错的情况,Nginx会尝试另一台后端服务器。Nginx 选定新的服务器以后,会先调用此函数,以重新初始化 upstream 模块的工作状态,然后再次进行 upstream 连接。
process_header 处理后端服务器返回的信息头部。所谓头部是与 upstreamserver 通信的协议规定的,比如 HTTP 协议的 header 部分,或者 memcached 协议的响应状态部分。
abort_request 在客户端放弃请求时被调用。不需要在函数中实现关闭后端服务器连接的功能,系统会自动完成关闭连接的步骤,所以一般此函数不会进行任何具体工作。
finalize_request 正常完成与后端服务器的请求后调用该函数,与 abort_request 相同,一般也不会进行任何具体工作。
input_filter 处理后端服务器返回的响应正文。Nginx 默认的 input_filter 会将收到的内容封装成为缓冲区链 ngx_chain。该链由 upstream 的 out_bufs 指针域定位,所以开发人员可以在模块以外通过该指针 得到后端服务器返回的正文数据。memcached 模块实现了自己的 input_filter,在后面会具体分析这个模块。
input_filter_init 初始化 input filter 的上下文。Nginx 默认的 input_filter_init 直接返回。
  1. 负载均衡模块
    负载均衡模块用于从upstream指令定义的后端主机列表中选取一台主机。Nginx先使用负载均衡找到一台主机,再使用upstram模块实现与这台主机的交互

六.其他模块

  1. core模块:Nginx的启动模块
  2. event模块:监听后建立的连接
    accept锁:80端口是个进程所共享的,避免多个进程同时调用accept
    nginx事件处理是根据触发顺序在一个大的循环里依次处理的
    nginx对个进程的请求处理的均衡性做了优化,负载高时,进程抢到的锁过多,会导致这个进程被禁止接受访问一段时间
    定时器:需要用到超时时用到定时器机制,使用红黑树(有序的二叉平衡树,比较理想的二叉树)来构造定时器,二叉树的值是超时时间,每次查找最小值,过期则删除节点直至所有超时节点都被删除
  3. nginx: 运行方式,异步非阻塞
    nginx配置url中有api的进行反向代理

https加密体系

Posted on 2018-07-12 | In 加密

三轮加密过程:(1)RSA (2)HMAC (3)一轮加密
HTTPS = HTTP+加密+认证+完整性保护
HTTPS:HTTP通信接口部分用SSL(安全套接字层)和TLS(安全传输层协议)

一.连接建立的过程:非对称加密算法

对象 过程说明 对象 备注
客户端浏览器 过程说明 服务器 备注

网络安全(计算机网络第七版)

Posted on 2018-07-10 | In 加密

一.网络安全问题概述

  1. 通信面临的两大类威胁:主动攻击(流量分析)和被动攻击(截获)
  2. 主动攻击:篡改、恶意程序、拒绝服务DoS
    篡改:篡改网络上传送的报文
    恶意程序:(1)计算机病毒
    (2)计算机蠕虫:将自身从一个节点发送到另一个节点并自动运行的程序
    (3)特洛伊木马:
    (4)逻辑炸弹:当本地运行满足某种特定条件时,执行其他特殊功能
    (5)后门入侵:
    (6)流氓软件:未经过用户允许就安装并损害用户利益的软件
    拒绝服务DoS:攻击者向互联网上的某个服务器不停的发送分组,导致服务器无法正常提供服务(分布式拒绝服务:从互联网上成千上万个网址集中攻击一个网站)
  3. 安全的计算机网络
    (1)保密性
    (2)端点鉴别
    (3)信息的完整性
    (4)运行的安全性:访问控制
  4. 数据加密模型
    (1)一般的加密模型:用户A向B发送明文X,通过加密算法E运算后,得出密文Y。Y=Ek(X)
    接受端通过解密算法和解密密钥解出明文
    (2)密码编码学+密码分析学=密码学

二. 两类密码体制

  1. 对称密钥密码体制
    (1)加密密钥和解密密钥使用相同的密码体制
    (2)数据加密标准DES:DES是一组分组密码;DES的保密性在于对密钥的保存,但是算法是公开的;密钥有56位
  2. 公钥密钥密码体制
    (1)使用不用的加密密钥和解密密钥
    (2)提出背景:解决相同密钥在接发双发存储的问题,对数字签名的需求
    (3)RSA体制
    (4)加密密钥(公钥)PK公开,解密密钥(私钥)SK需要保密
    (5)密钥体制的加密解密过程:
    1
    2
    3
    密钥对产生器产生出接收者B的一对密钥,发送者A的PK就是接受者B的公钥,B的SK即为私钥保密 
    ----> A用B的公钥PKB,通过E运算对明文X加密,得到密文Y
    ----> B用自己的私钥,通过D运算进行解密,恢复出明文X

PKB到SKB是“计算上不可能的”
公钥可用来加密,但是不可以用来解密
先加密后解密,后者先解密后加密的结果相同
(6)任何加密方法的安全性取决于密钥的长度,以及攻破密文所需的计算量

三. 数字签名

  1. 以下的三种功能:
    (1)接受者可以进行报文鉴别
    (2)报文的完整性
    (3)不可否认
  2. 签名过程:对报文签名并不对报名加密
    (1)A用其私钥对报文X进行D运算
    (2)A把经过D运算得到的秘文传给B
    (3)B为了核实签名,用A的公钥进行E运算,还原出明文

四. 鉴别

  1. 鉴别是要验证通信的双方的确是自己所要通信的对象,而不是其他的冒充者,并且传送的报文是完整的,没有被他人篡改过
  2. 鉴别和授权
    (1)授权涉及所进行的过程是否被允许
    (2)鉴别可分为报文鉴别(端点鉴别和报文完整性的鉴别)和实体鉴别(仅鉴别发送报文的实体,可以是一个人,也可以是一个进程,即端点鉴别)
  3. 报文鉴别
    (1)密码散列函数(相对简单的方式)
    密码散列函数实际上是单向函数
    (2)实用的密码散列函数MD5(报文摘要)和SHA-1(安全散列算法)
    密钥的产生、分配、注入、验证和使用
    (3)报文鉴别码
  4. 给出一个错误的流程
    (1)用户A根据自己的明文X计算出散列H(X)
    (2)用户A把H拼接在明文X后面,生成拓展的报文(X,H),发送给B
    (3)B收到(X,H),根据散列的长度为已知的固定值,可以把X和H区分开
    (4)B根据散列函数的运算,计算出收到的明文X的散列H(X)
    攻击者容易仿制
  5. 防范攻击:对散列进行一次加密
    avatar
  6. 实体鉴别:报文鉴别对每一个收到的报文都要鉴别报文的发送者,实体鉴别只需在系统接入的全部持续时间内对和自己通信的对方实体只需验证一次
    “一次一数”:避免重放攻击

五.密钥分配(密钥的产生、分配、注入、注册和使用)

  1. 对称密钥的分配
    A.所需的密钥数量过大:n^2问题;同时存在如何安全的分配共享的密钥的问题
    B.目前常见的密钥分配方式:设立密钥分配中心KDC,给需要进行秘密通信的用户临时分配一个会话密钥
    密钥分配过程:(1)用户A向KDC发送明文,说明想和A通信,明文中包含A和B在KDC中登记的身份
    (2)KDC用随机数产生“一次一密”KAB,向A发送报文,报文包含会话使用的密钥KAB和请A转给B的一个票据(ticket),票据用B的密钥KB加密过,包含A和B在KDC登记的身份
    (3)B收到A转来的票据并使用自己的KB解密,就可知道要和A通信,并获得KAB
    C.密钥分配协议KerberosV5
  2. 公钥的分配
    A.不可随意公布公钥
    B.认证中心CA

github添加或者删除分支

Posted on 2018-07-09 | In github

一. 添加分支

  1. 通过github客户端,添加分支后,进行同步
  2. 通过terminal
    (1)git branch //查看当前git的分支情况
    (2)git branch 分支名 //新建分支
    (3)git checkout 分支名 //切换到新建分支
    (4)git branch //重新查看分支
    (5)git push -u orogin 分支名 //同步到github

二. 删除分支

  1. terminal
    git push origin :分支名

AssetPipeline

Posted on 2018-07-09 | In Ruby

Asset Pipeline

合理组织应用的静态资源文件

一.

  1. 连接静态资源,减少渲染网页时的请求次数
    Javascript、CSS –Sprockets–》 主js、css文件
    在production下,Rails在每个文件名中插入SHA265指纹,以便web浏览器缓存
  2. 简化、压缩静态资源
  3. 使用更高级语言编写 e.g SaaS

二. 指纹识别(可以设置关闭)

可通过设置HTTP首部来建议所有缓存(CDN、ISP、网络devices或web浏览器的缓存)都保存该文件副本
Sprockets使用指纹:在文件名中添加Hash

三. Asset pipeline

  1. 原rails放在public中,asset pipeline放在app/assets
    静态资源文件放在app/assets,进行预处理

Sprockets中间处理(添加指纹)
2.不要使用require_tree指令,在config/application.rb下配置

清单文件是不是要添加?
js文件夹和css文件夹javascripts、stylesheets
官网只介绍了css和js文件添加清单文件,在清单文件中添加//=require_tree .
3.app/assets 应用自有的静态资源文件
lib/assets 存储自有代码库的静态资源文件(共享)
vendor/assets 第三方代码库的静态资源文件

四.预处理

  1. 顺序 .coffee.erb 先按erb文件处理,再按coffee文件处理

五.开发环境

按清单文件中指定的顺序处理静态资源文件
e.g app/assets/javascripts/application.js
//= require core
–生成HTML–》

1
2
<script src="/assets/core.js?body=1">
//body=1 为参数(sprockets)

六. 生产模式

1
2
3
<%= javascript_include_tag "application">
//生成HTML
<script src="/assets/application......js"></script>

七. CDN内容分发网络

各地服务器的副本,减小服务器压力


Asset Pipeline配置

  1. 产品环境下编译,在项目下运行rake assets:precompile RAILS_ENV=production
    会将app/assets/javascript/application.js、app/assets/stylesheets/application.js和app/assets子目录下的所有非js和css文件编译到public/assets目录下,目录下的文件均打上指纹
  2. 但是上述命令不会自动编译vendor/assets、lib/assets文件夹下文件,若要编译,则通过config.asssets.precompile来配置
  3. 编译到public/assets目录下,需要通过配置nginx、apache等web服务器来访问静态资源
  4. 引入第三方库 e.g 前端文件上传SWFUpload,借助flash

JBuilder配置

访问http…../hello.json

ActiveModel

Posted on 2018-07-09 | In Ruby

提供ActiveRecord的部分model,但不受数据库限制,任何ruby类都有model行为不使用数据库的数据需求

  1. validator
    验证需要的字段,具有valid?方法,可以返回布尔值
  2. 有Active Record,class继承自ActiveRecord::Base
    –解除继承关系–》输入验证失败
    –Avtice Model独立验证–》 加载Validations模块和提供getter方法属性
  3. 1
    2
    include ActiveModel::Validations
    attr_accessor :name,:email,:content

–》controller继承自ApplicationController,Message.new和Message.save会失效,Message.new用initialize方法调用send;Message.save用message.valid?替代

  1. attr_accessor定义成员变量时定义get和set方法

微信小程序-蓝牙

Posted on 2018-07-05 | In 微信小程序

一.硬件部分

  1. HC-08 蓝牙模块 4.0BLE主从一体 CC2540 无线串口透传模块 BLE串口通信
  2. 硬件官网
    汇承官网
  3. 基本连接教程
    avatar
    注意:串口模块和usb to ttl的连接方式

二. Windows串口调试助手

  1. 下载串口调试助手
  2. 设置默认波特率为9600

三.手机App测试

  1. LightBlue和Windows的调试
    avatar
    avatar
    avatar
    avatar
    注意:由图4可以看出串口通信的serviceId的UUID为FFE0(读写UUID)
  2. Android和Windows的调试

四.微信小程序初始化连接

  1. 初始化蓝牙适配器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    wx.openBluetoothAdapter({
    success: function (res) {
    console.log('初始化蓝牙适配器成功' + JSON.stringify(res))
    that.msg = '初始化蓝牙适配器成功'
    wx.showModal({
    title: '蓝牙适配情况',
    content: '初始化蓝牙适配器成功'
    })
    },
    fail: function () {
    that.msg = '初始化蓝牙适配器失败'
    wx.showModal({
    title: '蓝牙适配情况',
    content: '蓝牙适配失败,请检查手机蓝牙和定位功能是否打开'
    })
    },
    complete: function () {
    console.log('初始化蓝牙适配器完成')
    }
    })
  2. 开启蓝牙搜索,并获取蓝牙设备列表 wx.getBluetoothAdapterState –> wx.onBluetoothAdapterStateChange –> wx.startBluetoothDevicesDiscovery –> wx.onBluetoothDeviceFound –> getBluetoothDevices

  3. 选择蓝牙设备获取相应的deviceId
  4. 连接蓝牙设备 wx.createBLEConnection –> wx.getBLEDeviceService(获取设备的ServiceId)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    wx.createBLEConnection({
    deviceId: deviceId,
    success: function (res) {
    console.log('蓝牙设备连接成功')
    wx.hideLoading()
    wx.getBLEDeviceServices({
    deviceId: deviceId,
    success: function (res) {
    that.deviceService = res.services
    for (var t = 0; t < that.deviceService.length; t++) {
    var service = that.deviceService[t]
    var serviceId = service.uuid.substring(4, 8)
    if (serviceId === 'FFE0') { //‘FFE0’为设备定义的读写UUID
    that.serviceId = service.uuid
    }
    }
    that.nowDevice = !that.nowDevice
    that.nowService = !that.nowService
    console.log('获取蓝牙设备Service' + res.errMsg)
    },
    fail: function (res) {
    wx.showModal({
    title: '设备Service信息',
    content: '蓝牙设备连接成功' + '\n' + '设备信息获取错误' + res.errMsg
    })
    }
    })
    },
    fail: function (res) {
    console.log('蓝牙设备连接失败,请稍后重试')
    wx.hideLoading()
    wx.showModal({
    title: '提示',
    content: '蓝牙设备连接失败,请稍后重试',
    duration: 2000
    })
    },
    complete: function () {
    console.log('蓝牙设备连接完成')
    wx.hideLoading()
    }
    })
  5. 连接设备同时关闭蓝牙搜索 wx.stopBluetoothDevicesDiscovery

  6. 向串口发送数据(重要)
    wx.getBLEDeviceCharacteristics –> success: wx.notifyBLECharacteristicValueChang (启用notify功能) –> success:wx.writeBLECharacteristicValue –> success:wx.readBLECharacteristicValue(必须读取,否则Android设备无法正常向串口发送数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
wx.getBLEDeviceCharacteristics({
deviceId: that.deviceId,
serviceId: that.serviceId,
success: function (res) {
console.log(res.characteristics)
that.deviceCharacteristics = res.characteristics
for (var i = 0; i < that.deviceCharacteristics.length; i++) {
that.characteristic = that.deviceCharacteristics[i]
that.characteristicProperties = that.characteristic.properties
if (that.characteristicProperties.notify === true) {
that.characteristicId = that.characteristic.uuid
wx.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.characteristicId,
success: function (res) {
console.log('开启notify成功' + that.characteristic.uuid)
for (let i = 0; i < dataView.byteLength; i++) {
var writeData = '0x' + dataView.getUint8(i).toString(16)
that.writeDatas = that.writeDatas + '\n' + writeData
}
wx.writeBLECharacteristicValue({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.characteristicId,
value: dataBuffer,
success: function (res) {
console.log('发送的数据:' + that.writeDatas)
console.log('message发送成功')
wx.showModal({
title: '数据发送成功',
content: that.writeDatas
})
wx.readBLECharacteristicValue({
deviceId: that.deviceId,
serviceId: that.serviceId,
characteristicId: that.characteristicId,
success: function (res) {
console.log('读取数据成功')
}
})
},
fail: function (res) {
// fail
console.log('message发送失败' + that.characteristicIdw)
wx.showToast({
title: '数据发送失败,请稍后重试',
icon: 'none'
})
},
complete: function (res) {
// fail
console.log('message发送完成')
}
})
},
fail: function () {
console.log('开启notify失败' + that.characteristicId)
}
})
// that.writeMessage(that.deviceId, that.serviceId, that.characteristicIdw, that.characteristicIdr, that.characteristicIdn)
}
}
},
fail: function () {
console.log('获取characteristic失败')
}
})
  1. 读取串口发送的数据 (重要)
    wx.getBLEDeviceCharacteristics –> success:wx.notifyBLECharacteristicValueChange –> success:wx.readBLECharacteristicValue –> wx.onBLECharacteristicValueChange

五.微信小程序蓝牙未启动,离开小程序开启蓝牙后再启动小程序

蓝牙页面启动流程

  1. 在onLoad中wx.openBluetoothAdapter
  2. 在onShow中判断当前蓝牙适配器的状态wx.onBluetoothAdapterStateChange –> 若更改成功,则wx.openBluetoothAdapter

六.微信小程序开发注意

  1. Android设备在readBLECharacteristicValu后可能会出现显示message传输成功但是串口调试助手收不到数据的情况
    解决方法:在writeBLECharacteristicValu后添加readBLECharacteristicValue
  2. 串口读写设备的时候注意转换数据格式,传输的数据格式为ArrayBuffer,需要转换才可以显示,直接console返回的res.value为空
    用到的转换格式代码
    1
    2
    3
    4
    5
    6
    7
    8
    let data = that.sendData.split(',')
    let dataBuffer = new ArrayBuffer(data.length)
    let dataView = new DataView(dataBuffer)
    for (let j = 0; j < data.length; j++) {
    dataView.setUint8(j, '0x' + data[j])
    }

    var writeData = '0x' + dataView.getUint8(i).toString(16)
1
2
3
4
5
6
7
8
ab2hex: function (buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer), function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
}
  1. 根据serviceId获取characteristicId时需要采用for循环获取,不使用for循环会无法开启notify,使用for循环会开启两遍,两次开启UUID相同,但是第一次显示开启成功,第二次显示开启失败
  2. 实际读取串口发送数据的位置为wx.onBLECharacteristicValueChang,wx.readBLECharacteristicValue返回的res中只有接受信息是否成功的信息
  3. 问题:若手机蓝牙未启动,初始化页面无法成功开启蓝牙适配器,重新打开蓝牙后,页面无法重新开启蓝牙适配器
    解决:因为只在onLoad中定义了开始蓝牙适配器,没有在onShow中定义,通过《六》中来解决
    注意:必须在onShow中先进行判断,再选择是否调用wx.openBluetoothAdapter,否则在第一次启动页面的时候调用两次wx.openBluetoothAdapter,wx.showModal会显示两次(初始化页面的时候onLoad后会调用onShow)

比特币源码

Posted on 2018-07-05 | In 区块链

bitcoin

人人都懂区块链(笔记)

Posted on 2018-07-05 | In 区块链

一.数字货币介绍

比特币的源代码(大约有几万行)

  1. 区块链人群分布:币圈+链圈+矿圈
    区块链是计算机和金融完美结合体
  2. 数字货币的产生环境
    (1)数组货币是计算机密码学+分布式P2P网络+经济学+社会学的产物
    (2)数字货币是一个去中心化的理论模型,没有中央银行
    (3)数字货币是为了应对超发货币导致的通货膨胀
    (4)数字货币解决了信任权证问题
  3. 什么成为数字货币
    法币:国家信用背书
    数字货币:用技术背书(e.g 比特币,以太坊)
    支付宝和微信是法币的一种延伸,并非为数字货币

二.比特币介绍(一)

  1. 什么是比特币BTC:一种去中心化的数字货币(加密货币)
    (1)比特币白皮书:《比特币:一种点对点的电子现金系统》
    (2)BTC可以全世界流通,可以任意切割
    (3)1BTC = 1亿聪(Satoshi)
  2. 比特币BTC分布式网络节点
    节点和节点之间通过IP地址连接,形成网络
  3. 比特币网状节点
    (1)P2P点对点分布式系统
    (2)全世界网状相连
    (3)任何人都可以随时加入和退出
    (4)节点和节点平等
    (5)交易所、矿池、Bitcoin客户端都是其中的一个参与节点(全节点/钱包)
  4. 比特币全节点/钱包
    (1)钱包管理Wallet
    (2)挖矿管理Miner—银行结算中心
    (3)区块链数据Full Blockchain—-账本
    (4)网络路由节点Network Routing Node—-管理节点和节点之间的连接
    比特币的节点可以不是全节点,不同节点承担不同的角色
  5. BTC特点
    (1)比特币总量2100万枚,永不增发
    (2)永远不会通货膨胀,可能会通货紧缩
    (3)去中心化流通货币
    (4)转账有手续费(按照交易字节收费)
    (5)比特币交易,账号全部匿名
    (6)每隔大约10分钟全球会产生一个新的区块(当前是12.5BTC+手续费)—–相当于BTC奖励
    (7)一个区块包含奖励50BTC
    (8)每隔21万个区块就会BTC奖励减半,大约4年半减半一次

三.比特币钱包(Bitcoin Core)

  1. 比特币钱包下载
    Bitcoin Core 全节点 钱包 冷钱包(没有网络也可以产生账号)
    在交易所的钱包为热钱包
  2. 比特币钱包:余额查询,给对方转账,同步下载账本/区块
  3. 比特币账号:1开头为一次签名,3开头为多次签名
  4. 比特币转账费用:与金额无关,手续费和转账这条记录的字节数有关系,同时给多个人转账则手续费会更高;交易费越高,交易越快,中间有排序算法
  5. 比特币网络:主网络(交易网络)和测试网络(供开发使用)
  6. 地址离线产生,可以产生任意多的地址

四.比特币地址(账号)机制

  1. Wif格式
    (1)长度为34位
    (2)以1或者3(多重签名地址:多人验证)开头
  2. 私钥:一个BTC地址对应一个私钥
  3. 比特币地址产生流程
    私钥 —> 公钥 —> 公钥哈希 <---> 钱包地址
  4. 调试窗口
  5. 比特币地址特点
    (1)比特币地址有自我校验功能
    (2)比特币地址完全是离线生成的
    (3)比特币地址概率上大约200年才会有可能2个地址完全相同
    (4)有了私钥就有了比特币地址
  6. 长期持有比特币
    (1)用钱包产生一个BTC地址
    (2)然后把比特币地址的私钥坝村下来
    (3)给别人自己的比特币地址
    (4)在线查询余额(区块链浏览器)

五. 钱包安全

  1. 热钱包(交易所)
    交易所自己控制,不会给用户私钥
  2. 热钱包(钱包App)
    App团队也可知道私钥
    手机钱包App需要给用户提供私钥,但是比冷钱包方便,易用
  3. 钱包地址安全

六.密码学哈希Hash散列算法

  1. 大量使用计算机密码学
  2. 哈希散列算法
    (1)把一段任意长度的数据变成均匀分布固定长度的数据
    (2)Hash不可逆
    (3)在任何电脑,手机,或者笔算Hash值都是一样的—–不依赖于设备
    (4)y = Hash(x) 已知x可以得到y,反之不可以
    (5)HASH散列就像一个人的指纹
    (6)HASH的结果就是均匀分布
  3. HASH摘要算法
    (1)MD5
    (2)安全哈希算法
    a. SHA1 160位
    b. SHA256 256位
    c. SHA512 512位
    d. RIPEMD-160 160位
  4. 比特币中Hash的用处:进行分组验证
    (1)Hash公钥有统一的长度
    (2)Hash和解密一起做验证,签名算法。(https协议中常用)
    (3)挖矿Hash碰撞算法
  5. Hash碰撞
    (1)给定一个元数据,如何填充一段数据,结果是满足一定的嘴个
    (2)挖矿:给定数据hellobitcoin,后面追加任意数据(碰撞数),满足Hash最前面有5个0;前面的零越多,难度就会越大
  6. 比特币挖矿(Hash碰撞)
    挖矿就是找出一个值nonce(幸运值),小于一个目标值target

检查域名过期

Posted on 2018-07-04 | In 服务器
  1. 检查nginx
    nginx -t
    ps -ef | grep nginx
  2. 找到原来使用的域名
    在crontab里面有个可执行程序用于数据处理的,在这个可执行程序的统计目录下面有其源代码,这个源代码里面是有使用的域名
  3. 用一个新的域名去替换掉过期的域名,重新进行域名解析。
  4. 修改nginx配置文件中对应条目的域名,保存并重启nginx
    将crontab里面有个可执行程序同级目录下面的源码中的域名替换成新的域名,然后需要重新编译一下
1…345…9

Root

87 posts
20 categories
23 tags
© 2018 Root
Powered by Hexo
|
Theme — NexT.Mist v5.1.4
本站总访问量 次 | 有人看过我的博客啦