第一步:申请公众号测试接口
第二步:添加测试用户
第三步:添加消息模板
代码:获取动态ACCESS_TOKEN (有效期7200)
$appid='wxcfd6d103e4d5b35d';
$secret='60504239fe7597a9653b6272ae149369';
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret";
$token = getJson($url);
$access = $token["access_token"];
print_r($token);
print_r("\n");
发送模板消息
一定要注意json格式 ,否则会返回POST数据格式不正确
$url ="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access;
$data1 = '{
"touser":"o4f0Wv5nRBQMCzZ1AsDlq_9OsOrU",
"template_id":"HMnswJkdFHz_ZcINVzpuYE88PGMH20j4Rybr9BVfcjA",
"url":"http://www.rainfly.cn",
"data":{"frist":{"value":"提醒事件已经到了!","color":"#ff0000"}}
}';
function send_post($url, $post_data) {
$postdata = http_build_query($post_data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $post_data,
'timeout' => 15 * 60 // 超时时间(单位:s)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
//file_put_contents('access.json', $result);
//print_r($result);
//return $result;
}
send_post($url, $data1);
测试截图
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
由于常驻内存继而创建新的进程会出现资源的同步互斥现象;
Servlet: 同CGI程序 用来处理当前HTTP server交互数据
测试源码:
web.xml 文件中 指明项目访问路径 servlet-pattren 打开Tomcat 通过多开多个浏览器进行访问查看全局变量i的数值
全局变量在多线程访问时不断改变
需要将多个线程访问的资源加上锁,现在这种做法是给Servlet对象加了一把锁,保证任何时候都只有一个线程在访问该Servlet对象里面的资源,这样就不存在线程安全问题了
synchronized (this) { //Java中每个对象都有一把锁,这里的this指的就是servlet对象
response.setContentType("text/html");
i++;
String s=i+"";
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
response.getWriter().write(s);
}
首先需要安装pcntl_ 拓展
PHP -M 查看是否存在这两个文件
测试文件 test.php
<?php
header('content-type:text/html;charset=utf-8' );
// 必须加载扩展
if (!function_exists("pcntl_fork")) {
die("pcntl extention is must !");
}
$ppid = posix_getpid();
$pid = pcntl_fork();
printf("\n");
if ($pid == -1) {
throw new Exception('fork子进程失败!');
} elseif ($pid > 0) {
cli_set_process_title("我是父进程,我的进程id是{$ppid}."); //父进程名称
while (true)
{
echo "我是父进程 ID =".$ppid;
printf("\n");
sleep(3);
}
} else {
$cpid = posix_getpid();
cli_set_process_title("我是{$ppid}的子进程,我的进程id是{$cpid}.");//子进程名称
while (true)
{
echo "我是子进程 ID=".$cpid;
printf("\n");
sleep(3);
}
}
?>
运行PHP index.php就可以看到脚本线程的效果了
近期项目需要,研究一下GatewayWorker一款开源PHP。
使用数据库进行记录。
配置好开发环境。 http://doc2.workerman.net/326102
操作数据库 需要创建 /Config/Db.PHP 进行配置端口
配置文件如下:
<?php
namespace Config;
class Db
{
public static $db = array(
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => 'root',
'dbname' => 'db',
'charset' => 'utf8',
);
}
之所以在 /Config/Db.PHP 的namespace下面操作 是由于 /Lib/Db.PHP 文件中函数
public static function instance($config_name)
{
if (!isset(DbConfig::$$config_name)) {
echo "\\Config\\Db::$config_name not set\n";
throw new Exception("\\Config\\Db::$config_name not set\n");
}
if (empty(self::$instance[$config_name])) {
// $config_name 实际传递过来的字符串 组成了 $db 一个变量进行赋值
$config= DbConfig::$$config_name;
self::$instance[$config_name] = new DbConnection($config['host'], $config['port'],
$config['user'], $config['password'], $config['dbname']);
}
return self::$instance[$config_name];
}
继而在Event.PHP 文件中可以访问数据库进行操作
public static function onConnect($client_id) {
//通过config 连接数据库成功
$db = Db::instance('db');
//数据库插入语句
$db->query("INSERT INTO Persons VALUES ( 'admin', 'pass', 'w', 15)");
Gateway::sendToAll("$client_id login\n");
}
其中Event.PHP 需要包含
use \GatewayWorker\Lib\Db;
需求:编译安装QT 5.8.0 ARM +linux 版本
环境:Ubuntu 14.04 32bit
个人需要编译安装了 i386-linux-Qt5.8.0,
第一步:
下载文件
Qt官网下载:http://download.qt.io/archive/qt/
qt-opensource-linux-x64-5.8.0.run 这种类型是编译好的可以运行的x64位的i386的版本。
我们需要进入 single/ 内qt-everywhere-opensource-src-5.8.0.tar.xz 直接下载源码
我之前已经安装好了交叉编译工具
第二步
解压文件
找个英文目录,把qt-everywhere-opensource-src-5.8.0.tar.gz放进去。
用终端解压:tar -zxvf qt-everywhere-opensource-src-5.8.0.tar.gz
最好别右击“提取到此处”,这个解压好像和命令解压不同。
第三步:
修改编译配置文件:
vim qt-everywhere-opensource-src-5.8.0/qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf
(注意我的改动)
#
# qmake configuration for building with arm-linux-gnueabi-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
QT_QPA_DEFAULT_PLATFORM = linux #eglfs
QMAKE_CFLAGS += -O2 -march=armv7-a
QMAKE_CXXFLAGS += -O2 -march=armv7-a
# modifications to g++.conf
QMAKE_CC = arm-linux-gnueabi-gcc
QMAKE_CXX = arm-linux-gnueabi-g++
QMAKE_LINK = arm-linux-gnueabi-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabi-g++
# modifications to linux.conf
QMAKE_AR = arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabi-objcopy
QMAKE_NM = arm-linux-gnueabi-nm -P
QMAKE_STRIP = arm-linux-gnueabi-strip
load(qt_config)
注意:
这里指定了编译arm版qt所使用的编译器,与后期QtCreator项目的编译器是一样的。
如果你是用的是arm-none-linux-gnueabi-gcc,那么每一项都需要修改为arm-none-linux-gnueabi-。
#这里提前解释一下,第三步中已经指定好了编译器版本,所以第四步不需要指定了。
#第四步中的-xplatform linux-arm-gnueabi-g++是对应qmake.conf所在的文件夹,代表了编译的Qt库的版本。
第四步:
配置编译参数,用./configre -help 可以查看参数。
我的配置是(去除掉了一些用不到的选项):
./configure -release -opensource -confirm-license -xplatform linux-arm-gnueabi-g++ -prefix /usr/local/qt5.8-nomake examples -no-opengl -no-iconv -silent -qpa linuxfb -no-gtk -qt-libjpeg -qt-libpng
注意:
1、-xplatform linux-arm-gnueabi-g++ ,指定了编译Arm版的QT库;
2、-prefix后面的配置为qt库需要安装的位置,这个需要根据你的安装位置自己指定。(如果不指定默认的安装位置是 /usr/local/Qtxxx)
第五步:
如果上面配置没有问题,接下来make:
$make
或者
$make -j2 /CPU 几个核可以使用“-j几”,核多编的快*/
第六步:
安装:$sudo make install
在这里加sudo是因为,安装时会将库文件复制到上面第四步配置的安装目录( /usr/local/qt5.8)。
usr目录是需要root权限的。
好了,这是编译Qt5.8.0的过程。
编译平台插件:
由于Qt5以后,删除了嵌入式的QWS(Qt windows system-Qt窗体系统)换成QPA(Qt Platform Abstration -Qt平台抽象),平台插件在qt-everywhere-opensource-src-5.8.0/qtbase/src/plugins/platforms/下面。
有各种平台的插件,基于frambuffer的插件是lunuxfb这个文件夹下,其他的还有android、ios、winrt、windows等等,需要什么平台的编译就是了。
平台是基于Windows 10 x64、QT 5.8.0 编译环境
数据库操作要点 注意数据库
1.要将mysql中 mysql\libmysql.dll文件复制到\Qt\Qt5.8.0\5.8\mingw53_32\bin中
2.
// 打开MySQL
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); //需要打开那个数据库,必须选择驱动
db.setHostName("localhost"); //查看帮助文档
db.setDatabaseName("mydata");
db.setUserName("root");
db.setPassword("");
3.
在此文章之前已经使用和分析过mosquito作为 broker开放 1883和9001端口的MQTT功能,现在测试使用emqtt,且深入研究websocket的作用实现。
测试环境是 Ubuntu14.04 x64 位直接下载
安装步骤:
# 启动emqttd
./bin/emqttd start
# 检查运行状态
./bin/emqttd_ctl status
# 停止emqttd
./bin/emqttd stop
web控制台默认端口 18083(阿里云服务器需要在安全策略组中开放端口)
启动成功后登陆后台:查看websocket连接是否成功,检查端口8083和1883是否打开
具体配置emqtt: http://www.emqtt.com/docs/v2/config.html#
搭建完成后调试websocket功能;
本地搭建好web服务器: http://www.rainfly.cn/?post=257
加入调试文件
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
<title>websocket</title>
<script type="text/javascript">
client = new Paho.MQTT.Client("60.205.191.68", Number(8083), "");//建立客户端实例
function MqttConnect() {
client.connect({onSuccess:onConnect});//连接服务器并注册连接成功处理事件
function onConnect() { // 连接成功的回调函数
console.log("onConnected");
client.subscribe("rain");//订阅主题
}
}
client.onConnectionLost = onConnectionLost;//注册连接断开处理事件
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
console.log("连接已断开");
}
}
//接收消息
client.onMessageArrived = onMessageArrived;//注册消息接收处理事件
function onMessageArrived(message) {
//console.log("收到消息:"+message.payloadString);
console.log("收到消息:"+message.payloadBytes[0]);
}
//发送消息
message = new Paho.MQTT.Message("hello");
message.destinationName = "rain";
client.send(message);
</script>
</head>
<body>
<div id="sse">
<a href="javascript:MqttConnect()">运行 WebSocket</a>
</div>
</body>
</html>
通过加入断点进行调试
设计思路:利用MQTT协议 实现底层硬件和web实时双向通讯。
mosquito:http://mosquitto.org/files/source/
libwebsockets:https://gitee.com/woniu201/libwebsockets
安装步骤:
1.下载并编译liewevsocket
$ tar zxvf libwebsockets-1.4-chrome43-firefox-36.tar.gz
$ cd libwebsockets-1.4-chrome43-firefox-36
$ mkdir build
$ cd build
$ cmake ..(PS:apt-get install cmake 安装cmake工具)
$ make install
$ ldconfig
2.编译安装mosquito
$ wget http://mosquitto.org/files/source/mosquitto-1.4.2.tar.gz
$ tar zxvf mosquitto-1.4.2.tar.gz
$ cd mosquitto-1.4.2
更改configure.mk中
WITH_WEBSOCKETS:=no
变成(这一步是做WebSocket支持)
WITH_WEBSOCKETS:=yes
$ make
$ make install
$ cp mosquitto.conf /etc/mosquitto
编译过程可能遇到一些错误,
解决编译过程中找不到ares.h的问题:HTTP://www.cnblogs.com/xiaoerhei/p/3777157.html
mosquitoo 默认的端口是1883 websockets默认是9001
请在/etc/mosquitto/mosquitto.conf 的“Default Listener” 一节添加如下几行:
port 1883
listener 9001
protocol websockets
但是在阿里云ECS主机后台需要配置开放端口,9001端口无法开启,配置为1884.
3.添加用户且重新启动进程
$ adduser mosquitto
$ reboot
//重新启动进程
$ mosquitto -c /etc/mosquitto/mosquitto.conf -d
查看所有端口是否已经打开 netstat -anp
测试可以正常访问的!
由于多个项目需求(关于云服务器云支付等方式触发远程设备响应),之前使用过HTTPSQL轮询法,希望通过此种方法实现底层和云服务器数据交互,且大量占用服务器,只需要保持TCP连接。服务器始终保留其线程;
使用工具 HTOP 进程管理工具。(支持鼠标操作)
关于 HTOP使用方法: 百度
思路:通过linux网络编程,实现服务器和客户端一直保持连接,且服务器保留客户端唯一ID 和动态的socketfd
{中转服务器有一个map表,客户名+socket}
如果下位机有主动事件,则通过TCP协议将数据发送给终端处理 或者通过HTTP协议将数据提交到web服务器来处理
若服务器有主动事件,只可以通过TCP协议将指定数据发送到指定的ID中 (通过socketfd)(难点:ID和socketfd需要对应且动态变化(重启或者意外事件))
可以通过一个内存缓存区来存放 ID和socketfd; (如果利用内存缓冲区存放,若web服务器无法获得socket)
通过数据库存放;
使用linux C访问数据库 需要安装一个特定的包
sudo apt-get install libmysqlclient15-dev
最近项目上面需要用到刷卡系统,继而研究了一下对IC 相关的资料进行学习
项目平台 Windows 10
刷卡器 ZLG600A-T2 V1.03
上位机 QT4.8和zlg调试工具
IC卡 S50普通白卡
普通S50 IC卡存储结构:
MF1 卡分为 16 个扇区,每区有 4 块(块 0~块 3),共 64 块,按块号编址为 0~63。第 0 扇区的块 0(即
绝对地址块 0)用于存放芯片商,卡商相关代码,已经固化不可更改。其他各扇区的块 0,块 1,块 2 为数
据块,用于存贮用户数据;块 3 为各扇区控制块,用于存放密码 A,存取控制条件设置,密码 B。各区控
制块结构相同,具体如下图所示:
如果需要对其IC进行读写就需要验证秘钥AB,验证完成后可以对数据块(0~63块)进行任意读写
每个块拥有 16个字节空间,16x64=1024Bytes= 1K Bytes 即 容量为 8K 位 EEPROM;
注意:密码验证正确后,直接往第三区写数据就可以了,可以修改整个扇区的秘钥A,控制位,秘钥B,
注意控制位,因为控制位代表了新密码的权限及对数据位的控制,如果写入进去后就会把卡锁死了!
控制位 FF 07 80 69
参考文档 http://pan.baidu.com/s/1o85Id1C
SUPER TAB 工具
从http://www.vim.org/scripts/script.php?script_id=1643下载安装版。这个安装包跟先前的几个Vim插件不同,它是一个vba文件,即Vimball格式的安装包,这种格式安装包提供傻瓜式的安装插件的方法。
1)用Vim打开.vba安装包文件。
2)在Vim命令行下运行命令“UseVimball ~/.vim”。此命令将安装包解压缩到~/.vim目录。VImball安装方式的便利之处在于你可以在任何目录打开.vba包安装,而不用切换到安装目的地目录。而且不用运行helptags命令安装帮助文档。
3)在~/.vimrc文件中加入以下这行:
let g:SuperTabDefaultCompletionType="context"
CTAGS
http://www.cnblogs.com/willsonli/p/6555179.html