docker常用操作命令

创建

可以在hub.docker.com上创建一个新的repo,或者自己复制一个现有的repo.
绑定github后,也可以直接通过Dockerfile来发生成最新的镜像

查看镜像列表

docker images

查看容器列表

docker ps

查看所有的容器

docerk ps -a

查看最近创建的容器

docker ps -l

查找在指定 image 之后创建的 image 中的父 image

docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=xxxxxx)

获取镜像

docker pull name/reponame

删除

docker rm          Remove one or more containers
docker rmi         Remove one or more images

删除已经退出运行的容器

docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm

删除none镜像

docker images |grep none |awk '{print $3}'|xargs docker rmi

要删除全部image的话

docker rmi $(docker images -q)

停止所有容器

停止容器,才能删除所包含的image

docker stop $(docker ps -a -q)

运行

ssh登陆:

docker run -it  username/imagename /bin/bash

ssh登陆,并挂载本地目录,默认读写权限:

docker run -it -v 宿主绝对路径:docker绝对路径 username/imagename /bin/bash

attach

docker attach --sig-proxy=false $CONTAINER_ID

detach

docker没有专用的命令,目前不能使用eixit,因为会导致主进程退出。使用ctl+p+ctl+q来detach当前的进程

查看底层信息,比如IP等

docker inspect --format='{{.NetworkSettings.IPAddress}}' $CONTAINER_ID

commit

docker commit CONTAINER_ID docker_hub用户名/镜像名:tagname

push

docker push docker_hub用户名/镜像名:tagname

其他参考

资深专家都知道的 Docker 常用命令—源英文:Top Docker Commands Any Expert Should Know
Docker之容器的创建、启动、终止、删除、迁移等
docker入门——构建镜像

STM8 IWDG看门狗的使用说明

好久不搞stm8了,但朋友请教,还是帮忙确认下。主要是确认STM8的看门狗用法和喂狗时间问题,网上大把的代码样例,但是还是要刨根问底弄清楚细节,才可以用,否则就是埋雷。

大概的调用样例代码:

#define SYS_IWDG_OPEN        IWDG_KR=0xCC;
#define SYS_IWDG_FEED        IWDG_KR=0xAA;

void SystemIWDG_Config(void)   
{
    CLK_ICKCR|=S3;
    while((CLK_ICKCR&S4)==0);
    //STM8单片机需先执行0xCC指令,即先打开IWDG模块,否则IWDG工作不正常
    IWDG_KR=0xCC;                //启动看门狗
    IWDG_KR=0x55;                //使能模块访问
    IWDG_RLR=0xFF;               //溢出时间
    IWDG_PR=0x06;                //256分频 38000/256=148HZ T=6.7ms    
    IWDG_KR=0xAA;                //装载IWDG->RLR
}

代码的解释请参见以下的网络内容:

STM8独立看门狗介绍

独立看门狗模块可以用于解决处理器因为硬件或软件的故障所发生的错误。它由一个内部的128kHz的LSI阻容振荡器作为时钟源驱动,因此即使是主时钟失效时它仍然照常工作。

  • 独立看门狗功能说明
    图24是STM8独立看门狗模块的功能框图。
    当在键寄存器(IWDG_KR)中写入数值0xCC后,独立看门狗就被启动了,计数器开始从它的复位值0xFF开始递减计数,当计数减到0x00时就会产生一个复位信号(WDG RESET)。
    使用IWDG_PR和IWDG_RLR寄存器配置独立看门狗。IWDG_PR寄存器是用于选择驱动计数器时钟的预分频系数。每当KEY_REFRESH的数值(0xAA)写入到IWDG_KR寄存器时,独立看门狗将用IWDG_RLR的数值刷新计数器的内容,从而避免了产生看门狗的复位。
    IWDG_PR和IWDG_RLR寄存器具有写保护功能,要修改它们前,需首先在IWDG_KR寄存器写入KEY_ACCESS代码(0x55);在IWDG_KR写入0xAA将恢复写保护状态。

STM8_蜂鸣器功能图
(图24:STM8独立看门狗框图)

  • 硬件看门狗功能
    如果在IWDG_HW选择字节中使能了硬件看门狗的功能,在芯片上电时看门狗的功能被自动开启,如果软件不能及时操作键寄存器,则在计数器达到0x00时产生复位。关于选择字节的内容请参考数据手册中的说明。
  • 超时周期
    超时周期由计数器数值和时钟预分频器决定,下表列出了它们的数值。


(表26:STM8看门狗超时周期(假定计数器时钟为64kHz) )

键寄存器(IWDG_KR)

地址偏移值:0x00
复位值:未定义

STM8_键寄存器(IWDG_KR)

位7:0 KEY[7:0]:键值
软件必须在规定的时间内写入KEY_REFRESH数值,否则当计数器数值达到0时,看门狗会产生一个复位。
KEY_ENABLE数值=0xCC
写入KEY_ENABLE数值将启动IWDG。
KEY_REFRESH数值=0xAA
写入KEY_REFRESH数值将刷新IDDG。
KEY_ACCESS数值=0x55
写入KEY_ACCESS数值将允许对受保护的IWDG_PR和IWDG_RLR寄存器的操作

预分频寄存器(IWDG_PR)

地址偏移值:0x01
复位值:0x00

STM8_预分频寄存器(IWDG_PR)

位7:3 保留,必须保持为0。
位2:0 PR[2:0]:预分频系数
这些位是写保护的。它们用于指定对计数器时钟分频的分频系数。
000:分频系数=4
001:分频系数=8
010:分频系数=16
011:分频系数=32
100:分频系数=64
101:分频系数=128
110:分频系数=256
111:保留

重装载寄存器(IWDG_RLR)

地址偏移值:0x02
复位值:0xFF

STM8_重装载寄存器(IWDG_RLR)

位7:0 RL[7:0]:看门狗计数器重装载数值
这些位是写保护的(见14.2)。每次在IWDG_KR寄存器中写入0x
被传送到看门狗的计数器中,看门狗的计数器将重新从这个值开和时钟的预分频系数决定,见表26。

IWDG寄存器映像和复位数值


(表27:STM8 IWDG寄存器映像 )

 

官方手册原始内容,124页:

http://www.st.com/content/ccc/resource/technical/document/reference_manual/9a/1b/85/07/ca/eb/4f/dd/CD00190271.pdf/files/CD00190271.pdf/jcr:content/translations/en.CD00190271.pdf

本地下载备份:en.CD00190271

根据芯片手册中时钟的配置:

文章开头样例代码的看门狗最大喂狗时间大约1.725秒(38K时钟)

基于docker/虚拟机的esp32远程工作流

工作流框图

背景说明

  1. 为什么需要这套工作流–为了满足高效和灵活的开发方式
    • 因为我经常需要在公司和家里切换不同的电脑工作,所以编译环境需要在远程主机上,这样不同的工作机器都能访问相同的工作编译环境。
    • 因为esp32官方推荐的还是在linux下编译,所以最简单的就是我们的编译环境和工具链还是在linux下。但是我们日常的编码和硬件烧录还是在本地windows和mac的居多。所以就有了这一套本地环境和远程docker环境相互配合的工作流。我们可以在远程编译环境使用命令行高效编译,本地继续使用VSC等工具编码和烧录。
  2. 为什么用docker而不是虚拟机?
    • 因为docker更轻量小巧,结合hub.docker.com 用起来也更方便些,更具有灵活性。当然如果你就是喜欢用VM,也是可以的,这个流程仍然适用,只是挂载宿主的目录方式有所不同而已。
    • 使用docker另外一个好处是,你可以很方便的将你配置的开发环境通过hub.docker.com分享给需要的人。

工作流步骤

  • 选择对应的linux系统镜像创建我们的docker镜像,这里我们推荐选择ubuntu 16.04系统。
  • 启动时,我们用 -v 参数将远程宿主机的本地目录挂载进docker系统。
  • 按照官方esp32的编译环境要求,部署相应的工具链和环境。部署到我们映射的目录中,这样相关的工具和代码等都可以在宿主机里面可见,并且可访问。
  • 将挂载的目录通过samba或者sshfs共享给远程的编码机器(window或者MAC)环境,并且挂载到本地虚拟磁盘路径上。
  • 日常的编码和烧录,我们就可以像访问本都路径一样访问远程vps的开发路径。使用VSC编码,或者download tool进行开发板烧录。

docker镜像

最后,如果你对使用docker环境开发esp32感兴趣,也可以直接使用我目前在用的针对esp32的docker开发镜像。一键部署,开箱即用。

docker pull hiproz/ubuntu-esp32

参考

esp32 ubuntu开发环境搭建
docker常用操作命令
windows下实现esp32下载
sshfs的安装

windows下实现esp32下载

  1. UI工具下载
    使用官方的UI工具 flash_download_tools 但是始终提示如下的错误:
wxBitmap::CreateFromImage(): invalid image

同时UI工具弹框提示:找不到 ./RESOURCE/IDLE_S.bmb
根据日志,对相关模组做了重新安装:

pip install -U wxPython
pip install Pillow

安装后还是不行,遂暂时另寻他法。
2. python命令行下载
想起ubuntu下 make flash 命令后的下载命令,一想,我可以在windows下如法炮制啊:

 ./esp32/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port COM15 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 ./esp32/esp-proj/hello_world/build/bootloader/bootloader.bin 0x10000 ./esp32/esp-proj/hello_world/build/hello-world.bin 0x8000 ./esp32/esp-proj/hello_world/build/partitions_singleapp.bin

遇到问题:

No module named tools.list_ports

于是安装缺少的模块:

pip install pyserial --upgrade

再执行,同步重启设备,竟然顺利烧写成功了。
3. UI工具正常了
等方式2成功后,再尝试UI工具时,竟然顺利成功了。感情前面的失败是uart组件缺失导致的,日志提示真是坑啊。

最后还是一如既往的死磕,搞定!

windows下的端口映射

在某些情况下,我们要绕过一些失效的端口,就需要将一些默认的端口做端口映射。

端口映射,linux/unix中使用ssh命令,而windows中也有类似的命令netsh。客户端连接物理主机的“服务端口a”映射到“服务端口b”从而实现端口的变换。

命令如下

  • 可以查看存在的转发
    netsh interface portproxy show all

  • 添加一个IPV4到IPV4的端口映射
    netsh interface portproxy add v4tov4 listenport=22 connectaddress=ip connectport=port

  • 删除指定转发端口
    netsh interface portproxy delete v4tov4 listenport=port

例子

假定需要通过192.168.1.8的14941端口连接192.168.1.118的22端口,则需要在192.168.1.8主机的命令行输入如下语句
– 操作系统开启了主机防火墙,需要放行TCP 14941的入站连接
netsh interface portproxy add v4tov4 listenport=14941 connectaddress=192.168.1.118 connectport=22
– 取消上面配置的端口转发,可以用如下语句:
netsh interface portproxy delete v4tov4 listenport=14941
– 如果想查看已经配置了哪些端口转发,可以用如下语句:
netsh interface portproxy show v4tov4

更多命令,请查看帮助,都写得很清楚的。

centos7配置samba

  1. 开放端口
    确认自己本地的iptable 或者firewalld,打开对应的端口。
    如果是阿里云,还要开启对应ecs的安全组端口配置。
    建议:
    UDP 137-138
    TCP:139 445
  2. 确认SELinux的相关权限设置
    在没搞明白之前,先关闭,等调试通了后再开启,根据相关的问题来配置。不建议粗暴的关闭。
  3. 安装 samba
yum install samba
systemctl enable smb
systemctl start smb
  1. 创建用户

– 创建用户组
groupadd dev
– 创建用户
useradd -g dev aaa
– 设置用户的密码
passwd aaa
– 将用户添加到samba账号中
smbpasswd -a aaa
5. 配置samba
/etc/samba/smb.conf
参考配置:

# See smb.conf.example for a more detailed config file or
# read the smb.conf manpage.
# Run 'testparm' to verify the config is correct after
# you modified it.

[global]
        workgroup = SAMBA
        security = user

        passdb backend = tdbsam

        printing = cups
        printcap name = cups
        load printers = yes
        cups options = raw
        map to guest = Bad User
        log file = /var/log/samba/log.%m
[homes]
        comment = Home Directories
        browseable = no
        writable = yes
[public]
        comment = Public Stuff
        path = /data/share
        public = yes
[dev]
        comment = developer
        path = /dev
        valid users = @dev
  1. 参考
    https://www.cnblogs.com/muscleape/p/6385583.html
    https://wiki.centos.org/HowTos/SetUpSamba

wordpress用户页面按照修改时间显示文章

默认是按照发布时间来显示的,有时候我们希望按照修改时间来显示,最近修改的先显示。
修改方法如下:
在你的主题首页文件 index.php中类似以下代码之前:

while (have_posts()) : the_post();

添加:

$posts = query_posts($query_string . '&orderby=modified');

这样在首页的排序就已经达到效果啦,如果你其它页面也需要这样安装修改排序,那么同理即可,修改其它页面就行了。

docker软件安装

为了保持最精简的系统,默认的系统镜像是没有额外应用的,任何需要的应用几乎都要自己来安装。
默认docker使用的是宿主网卡,只可以直接访问外网的,如果访问外部网络有问题,请检查安装过程或者使用的镜像。

关于linux选用哪个系统好的问题,理论上hub.docker.com上各个官方的都差不多,哪个用的习惯就用那个。抛开具体的产品开发环境和团队系统要求,目前还是ubuntu的最多些。如果没有特殊要求,我们一般推荐ubuntu来做docker环境。

对于ubuntu新系统,第一步要 apt-get update,其他的系统同理。然后再安装其他需要的软件,否则可能提示找不到对应的包。

  1. ping
    apt-get install iputils-ping
    这个是必要的工具,方便来确认网络问题。

c语言变参的宏定义

#define debug(format, ...) fprintf(stderr, format, __VA_ARGS__)

等价于:

#define debug(format, args...) fprintf (stderr, format, args)

C99规范支持了可变参数的宏,可以用VA_ARGS传递…。
用法如下:

#include <stdio.h>

#define DEBUG(format, ...) printf(format, __VA_ARGS__)

int main(){
        int turn=1;

        printf("enter %s\n", __func__);
        DEBUG("test:%d\n",turn);
        return  0;
}

但这样又引入了一个新的问题,当…为空时,会导致链接错误。这里引入’##’操作。如果可变参数被忽略或为空,’##’操作将使预处理器(preprocessor)去除掉它前面的那个逗号。

#include <stdio.h>

#define DEBUG(format, ...) printf(format, ##__VA_ARGS__)

int main(){
        int turn=1;

        printf("enter %s\n", __func__);
        DEBUG("test:%d\n",turn);
        DEBUG("test\n");
        return  0;
}

参考:
宏中”#”和”##”的用法

一份VSC的本地设置

本地UI设置:

{
    "editor.tabSize": 4,
    "editor.formatOnSave": true,
    "clang-format.executable": "D:\\Program Files\\LLVM\\bin\\clang-format.exe",
    "git.path": "D:\\Program Files\\Git\\bin\\git.exe",
    "window.zoomLevel": 1,
    "explorer.confirmDelete": false,
    "git.confirmSync": false,
    "files.autoSave": "afterDelay",
    "editor.wordWrapColumn": 200
}

.clang-format 文件配置:

BasedOnStyle: llvm
BreakBeforeBraces: Linux
Language: Cpp
ColumnLimit: 0
ReflowComments: false
SortIncludes: false

#括号风格
BreakBeforeBraces: Custom
BraceWrapping:
  AfterEnum: false
  AfterStruct: false
  SplitEmptyFunction: false

关于DEBIAN_FRONTEND noninteractive的正确用法

DEBIAN_FRONTEND这个环境变量,告知操作系统应该从哪儿获得用户输入。如果设置为”noninteractive”,你就可以直接运行命令,而无需向用户请求输入(所有操作都是非交互式的)。这在运行apt-get命令的时候格外有用,因为它会不停的提示用户进行到了哪步并且需要不断确认。非交互模式会选择默认的选项并以最快的速度完成构建。请确保只在Dockerfile中调用的RUN命令中设置了该选项,而不是使用ENV命令进行全局的设置。因为ENV命令在整个容器运行过程中都会生效,所以当你通过BASH和容器进行交互时,如果进行了全局设置那就会出问题。

正确的做法 – 只为这个命令设置ENV变量
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3

错误地做法 – 为接下来的任何命令都设置ENV变量,包括正在运行地容器

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get install -y python3

我的示例如下:

FROM ubuntu:trusty
MAINTAINER mryqu 
RUN \
 DEBIAN_FRONTEND=noninteractive apt-get update && \
 DEBIAN_FRONTEND=noninteractive apt-get -y install wget curl && \
 DEBIAN_FRONTEND=noninteractive apt-get -y autoremove && \
 DEBIAN_FRONTEND=noninteractive apt-get clean

STM8 bootloader纪要

STM8 bootloader-UM0560

mcu:STM8L051F3P6,属于 STM8L Series low density

bootloder 支持

已经内置bootloader的mcu
bootloader group

没有内置bootloader的mcu

bootloder 执行流程图

bootloader执行流程图:

bootloder 传输设置

ota 同步消息SYNCHR=0x7F

支持传输的外设

从图上看,051F支持UART或者SPI
UART设置:1 start bit, 8 data bit, 1 bit 奇校验 ,1 stop bit
波特率:通过0x7F的传输,自动适配波特率,最大115200,最小4800.

传输回复
串口:1 start bit, 8 data bit, no parity bit, 1 stop bit,波特率自适应

SPI设置
• 8 data bit, MSB first
• Bit rate: Set by the host which acts as a master
• Peripheral set in slave mode with software management of NSS
• Data polarity: CPOL = 0 (SCK to 0 when idle), CPHA = 0 (the first clock transition is the
first data capture edge).

收到命令后,bl回复ACK 0x79

bootloder 外设选择

从资源的角度,我们倾向于使用spi做外设,因为uart可以预留来做用户调试用,但是目前官方提供了uart的串口下载PC客户端,方便测试。所以目前看使用uart作为bl外设可能更方便。这里也就要求选用单片机时,最好是多串口的设备。

bootloder 跳转地址表

关键点检测后,要跳转的地址表:

目前我们可以先考虑实现串口的版本,但是最后还是SPI的更实用。

完整文档:UM0560

ameba sdk的debugger设置

  1. setup

    两个配置项的内容:
$PROJ_DIR$\..\..\..\component\soc\realtek\8195a\misc\iar_utility\common\preload.mac
$PROJ_DIR$\..\..\..\component\soc\realtek\8195a\misc\iar_utility\common\8195a.ddf
  1. download

    配置内容:
    $PROJ_DIR$\tmp.board
  2. extra options

    配置内容:
    --drv_vector_table_base=0x0
    此选项如果没有设置,会出现 __vector_table 问题

STM32Cube 扩展包开发 checklist

STMCube 包括:
– STM32CubeMX,一个图形化配置工具软件,可以生成c语言的配置代码。
– 一个详尽的STM32Cube MCU开发包,为每个STM32系列提供:

-- STM32Cube HAL,涵盖所有外设。
-- Low-layer APIs,提供一个轻量快速的面向专家的接口层,LL只包含部分外设。
-- 一系列中间件,例如RTOS,USB,TCP/IP和图形界面等。
-- 一系列应用和示例。

简介

STM32Cube MCU Package 运行在 cortex-M 处理器上。

质量规范

  1. 确保所有工具兼容,不能有error和warnings。
  2. 开发要符合 MISRA C 编码标准,并且要进行静态代码分析。

封装规范

  1. 本地的STM32Cube MCU 组件包不能修改。release note 不能删除,不用的文件也不能删除,源代码也不能被修改。
  2. release notes应该包含以下的内容:
    — 主要变更点
    — 变更的内容,包括新开发的组件和被引用的组件。
    — 工具链,编译器
    — 支持的设备或者开发板
    — 局限性说明
  3. 每一个组件都应该有release note
  4. 文件或者相关的软件都要版本管理,并且在文件头或者release note中添加修改日期。
  5. 要求license 说明。
  6. 新的BSP驱动应该添加在 \Drivers\下。如果要添加新的组件,应该添加在\drivers\BSP\Components下。
  7. 新的中间件应该添加在 \Middlewares\Third_Party目录下。
  8. 用户示例应该添加到\Projects\下 ,并且遵循以下归类:
    — examples: 只使用HAL和BSP的例子。
    — Applications:使用中间件的例子。
    — Demonstration:全部使用的例子。
  9. example目录组织如下:
    — \Inc for header files
    — \Src for source files
    — \ toolchain preconfigured project, all temporary files haveto be deleted
    — ApplicationN_Name.ioc: STM32CubeMX
    project file
    — .extSettings: STM32CubeMX project
    additional settings file (optional, if needed)
    — \Binary containing binary file, using thisnaming format “USER_BOARD_REF_ApplicationN_Nam
    e_VX.Y.Z.bin”
  10. 使用TMC32CubeMX生成的例子
  11. .ioc .mxproject 和.extSettings文件必须和readme.txt文件在同一级目录,都在示例工程的根目录下。
  12. ioc 文件遵循 ApplicationN_Name.ioc格式的命名格式。
  13. 媒体文件应该放在 \Utilities\Media目录下。
  14. readme文件包含了每一个资源的copyright、license,务必要添加。
  15. 所有的上位机PC软件必须放在 \uTILITIES\pc+Software 下。
  16. 要为每一个示例添加预配置的EWARM,MDK-ARM,SW4STM32工程文件
  17. 顶层目录命名应该符合规范:STM32CubeExpansion____VX.Y.Z
  18. 发布的bin或者lib必须遵循:
    — 包含对应的头文件
    — release note
    — lib如果跟编译器相关,要遵循命名规则:LibraryNameV_CMx_C_O.a

中间件规范

  1. RTOS工程必须包含 CMSIS-RTOS API
  2. 一个新的中间件应该和硬件或者平台无关,并且有相应的接口层支持。
  3. 中间件要有中间件接口文件,可供用户定制或者更新。

文档规范

  1. 新增的组件都要有相应的API文档
  2. 每一个示例都应该有详尽的注释,功能描述和硬件设置说明。

APNs php客户端及静默推送

简介

关于APNs的工作原理,网上有大量的文章,建议学习apple的官方文档。通过APNs我们就可以通过服务器想APP推送想要的内容和事件。从而实现通知或者激活应用的目的。本文我们讲介绍如何搭建php的APNs推送以及如何实现静默推送。

APNs PHP 客户端

经过多方的验证,目前推荐这个:
https://github.com/immobiliare/ApnsPHP

证书

想要通过苹果服务器推送信息,必须要有合法的证书。很多人在推送这部分花了很多时间,很多情况是没搞清楚失败到底是代码的问题还是证书的问题。所以,我们需要先验证证书的合法和正确性。

推送时,我们要制作推送证书,我们要选择正确的类型,具体的制作过程可自行搜索,最终的证书类型如下:

先前我的文章推荐过Knuff,经过深入的实践,这里我推荐Easy APNS Provider,可以从MAC store下载。相比较Knuff,EAP更加的稳定强大。通过工具我们就可以先行验证证书的正确性,避免后面定位问题浪费更多的时间。

在MAC上用客户端向苹果发送推送服务器请求时,我们选择上面安装的证书就可以了。

PHP服务器证书

上面我们讲了怎么选择正确的客户端证书,当我们使用php 服务器推送时,我们还要做些额外的工作:

  • 打开“钥匙串”程序,(证书助理->从证书颁发机构请求证书),只填邮箱和常用名称,ca不用填,然后保存.certSigningRequest文件到磁盘。
  • 在iOS Dev Center 点击App IDs进入App ID列表。
  • 为 App 开启 Push Notification 功能。(推送证书分为两个版本,一个是Development版,一个是Production版,分别对应开发证书和发布证书。)
  • 上传刚才生成的.certSigningRequest文件,生成aps_development.cer推送证书,双击安装。
  • 打开“钥匙串”程序,(选择登录与我的证书选项后)找到IOS Push Services那条。
  • 右键导出,存储为cert.p12,(输入密码P*d),然后将该证书的折叠打开,导出“专用密钥”。存储为key.p12
  • 接下来打开终端执行下面的命令,生成的ck.pem就是我们在php脚本中要使用的证书。
#生成cert.pem
openssl pkcs12 -clcerts -nokeys -out cert.pem -in cert.p12
#生成key.pem(先输出导出key.p12时设置的密码P*d, 然后设置一个新的密码,如pushpwd,这个密码后面php推送时要设置)
openssl pkcs12 -nocerts -out key.pem -in key.p12
#合并成ck.pem
cat cert.pem key.pem > ck.pem

APNs PHP客户单配置

这个软件包的最新版本支持HTTP2,如果你的PHP的版本支持HTTP2,建议优先使用。开发包里面自带了几个sample,简单配置后基本就可以使用。这里我们以sample_push.php为测试对象。

如图所示,配置要点如下:
* 目标环境:sandbox还是production,对于appstore下载的目标,请选择ENVIRONMENT_PRODUCTION,对于开发中的版本,清选择ENVIRONMENT_SANDBOX
* 证书:填写证书的相对路径,这里最好时按照上面的步骤验证通过的证书
* 在上面的步骤中我们生成pem证书时,要求一个最少4位的密码,所以这个地方一定要设置密码,否则connect会失败
* device token:这里是我们要推送的目标的token。

测试通过的返回如下:

Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: INFO: Trying tls://gateway.sandbox.push.apple.com:2195... Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: INFO: Connected to tls://gateway.sandbox.push.apple.com:2195. Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: INFO: Sending messages queue, run #1: 1 message(s) left in queue. Fri, 13 Jan 2017 13:31:35 +0100 ApnsPHP[15355]: STATUS: Sending message ID 1 [custom identifier: Message-Badge-3] (1/3): 167 bytes. Fri, 13 Jan 2017 13:31:36 +0100 ApnsPHP[15355]: INFO: Disconnected.

device token

在上面我们提到了设备的device token,那么调试阶段如何获取这个token呢?在我们发起了注册请求后,系统会触发相应的消息回调。相关的参考代码如下:

-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    //读取APNS token
    NSString* _deviceToken = [[[[deviceToken description]
                                stringByReplacingOccurrencesOfString: @"<" withString: @""]
                               stringByReplacingOccurrencesOfString: @">" withString: @""]
                              stringByReplacingOccurrencesOfString: @" " withString: @""];
    QMLogDebug(@"apns token:%@",_deviceToken);
    NSUserDefaults * userDefault = [NSUserDefaults standardUserDefaults];
    [userDefault setObject:_deviceToken forKey:APNSTOKEN];
    [userDefault synchronize];
}

上面的deviceToken就获取了我们需要的token。

静默推送

ios最新的版本中已经支持了静默推送,静默推送时,客户端会收到消息,执行相应的动作,但不会做任何给用户的提示。在普通的推送中我们可以通过如下的代码实现静默推送的效果:

{
  "aps" : {
    "badge" : 0
  }
}

但是苹果还是专门定义了一个开关来表示静默推送 “content-available” : 1,由于此开关优先级较低,在静默推送的报文中不能出现alert,sound 等,否则就会变成普通推送。

静默推送的payload如下:

{
  "aps" : {
    "content-available" : 1
  }
}

静默推送的前提:
1. 只有app还在后台运行时,才能收到静默推送,否则推送了也没有用
2. 跟普通推送类似,苹果对频率和到达性都不做保证。

参考

How to generate a Push Notification certificate and download the Entrust Root Authority certificate

基于certbot的letsencrypt安装使用

# 起因

  • 前面的文章讲过,运营商环节会在用户加载内容的时候,在流中进行注入frame ,强行展示广告。
  • 如果你的server是给App提供web api的接口,由于苹果ATS的执行,你不得不所有接口都升级成HTTPS。

免费ssl证书

首选当时letsencrypt了,官方网站是:https://letsencrypt.org. 网上大把文章,但按照本人一贯的习惯还是去官网,避免被过时的信息误导,反而浪费更多的时间。
官方推荐的是cetrbot:https://certbot.eff.org/
根据本人的系统,实际的文档路径:https://certbot.eff.org/#centosrhel7-nginx

letsencrypt

安装

首先需要安装certbot:
默认centos7是不支持certot,你需要先安装EPEL:https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F
实际的安装包为:https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
下载后安装rpm。然后执行:

sudo yum install certbot

一路‘y’,安装完成:

Installed:
  certbot.noarch 0:0.9.3-1.el7

Dependency Installed:
  dialog.x86_64 0:1.2-4.20130523.el7                 pyOpenSSL.x86_64 0:0.13.1-3.el7                     python-cffi.x86_64 0:1.6.0-5.el7
  python-chardet.noarch 0:2.2.1-1.el7_1              python-enum34.noarch 0:1.0.4-1.el7                  python-idna.noarch 0:2.0-1.el7
  python-ipaddress.noarch 0:1.0.16-2.el7             python-ndg_httpsclient.noarch 0:0.3.2-1.el7         python-parsedatetime.noarch 0:1.5-3.el7
  python-ply.noarch 0:3.4-10.el7                     python-psutil.x86_64 0:2.2.1-1.el7                  python-pycparser.noarch 0:2.14-1.el7
  python-requests.noarch 0:2.6.0-1.el7_1             python-six.noarch 0:1.9.0-2.el7                     python-urllib3.noarch 0:1.10.2-2.el7_1
  python-zope-component.noarch 1:4.1.0-1.el7         python-zope-event.noarch 0:4.0.3-2.el7              python-zope-interface.x86_64 0:4.0.5-4.el7
  python2-acme.noarch 0:0.9.3-1.el7                  python2-certbot.noarch 0:0.9.3-1.el7                python2-configargparse.noarch 0:0.11.0-1.el7
  python2-cryptography.x86_64 0:1.3.1-3.el7          python2-dialog.noarch 0:3.3.0-6.el7                 python2-mock.noarch 0:1.0.1-9.el7
  python2-pyasn1.noarch 0:0.1.9-7.el7                python2-pyrfc3339.noarch 0:1.0-2.el7                pytz.noarch 0:2012d-5.el7

Complete!

开始

在已经有webserver运行的情况下,certbot推荐我们使用“webroot”插件。可以实现在不暂停web服务的情况下更新证书。

webroot:不需要停机你的web服务

certbot certonly --webroot -w AAA -d BBB

BBB是你要支持的域名,AAA是BBB当前已经可以访问的目录。

standalone:需要停机你当前服务器的80端口的服务

certbot certonly --standalone  -d xxx.com

以上每一条命令生成一个对立的目录,如果是多个域名就是合在一起的一个文件。如果要每个域名都生成独立的目录和文件,就要执行多次。

成功后:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/xxx/fullchain.pem. Your cert
   will expire on 2017-03-18. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

手动在nginx的conf中配置相关的路径就可以了:

ssl_certificate /etc/letsencrypt/live/xxx/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem;

续期

certbot renew

撤销

[root@rxblog certbot-0.22.2]# ./certbot revoke --cert-path /etc/letsencrypt/archive/xxx.com/cert1.pem
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Would you like to delete the cert(s) you just revoked?
-------------------------------------------------------------------------------
(Y)es (recommended)/(N)o: Y

-------------------------------------------------------------------------------
Deleted all files relating to certificate iwwenbo.com.
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Congratulations! You have successfully revoked the certificate that was located
at /etc/letsencrypt/archive/iwwenbo.com/cert1.pem

-------------------------------------------------------------------------------

OK,暂时告一段落。

Mac下零基础学习go语言-2-开发环境的搭建

环境介绍

  • 系统:OS X EI Capitan 10.11.1
  • go version:1.5.1

安装

下载最新的安装包 https://golang.org/dl/

mac下安装

直接点击,按照引导就可以完成安装。

linux下安装

linux下实际就是手动设置文件路径了,大概的动作如下:

#!/bin/bash
tar -C /usr/local -xzf go*.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile

最后重启,或者:

source /etc/profile

验证版本

终端验证,输入

go version
go version go1.11.2 linux/amd64

配置环境变量

设置环境变量,go默认安装在/usr/local/go 下面,参见:Mac OS X 配置环境变量

所以我们修改 .bash_profile:

export GOPATH=/Users/alex/dev/go
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN

注意:

  • 默认情况下GOROOT已经在安装时指定为安装目录了,是不需要设置的
  • GOPATH 设置成你的本地开发路径,而不是安装路径

设置完成后可以用 go env 命令检测

测试

在 GOPATH下 的src目录下创建项目demo。注意这个将是默认的bin档名。 然后在demo目录下创建main.go

package main

import (
  "fmt"
)

func main() {
  fmt.Println("hello world");
}

然后运行 go build demo,如果在demo项目目录下,直接 go build,完成后,在项目目录下生成 demo

直接运行 ./demo,就会输出 :hello world

DEBUG

初学者建议在LiteIDE下面debug,因为IDE直接UI支持,熟悉了以后也可以在命令行下面直接debug。第一次试用时要解决GDB的证书签名问题,可以参看网上同学给出的操作流程。

下面终于可以开始coding了!