server.php
6.1 KB
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<?php
require_once __DIR__ . '/simplewind/vendor/autoload.php';
require_once __DIR__ . '/simplewind/vendor/workerman/workerman/Autoloader.php';
use Workerman\Lib\Timer;
use Workerman\Worker;
//定义心跳时间
define('HEARTBEAT_TIME', 60);
global $worker;
//创建一个监听端口
$worker = new Worker("tcp://114.215.223.17:5001");
// 启动1个进程对外提供服务
$worker->count = 1;
// 新增加一个属性,用来保存uid到connection的映射
$worker->uidConnections = array();
$worker->onWorkerStart = function ($worker) {
global $db;
global $worker;
$db = new \Workerman\MySQL\Connection('rm-m5eblhc9o3515i25neo.mysql.rds.aliyuncs.com', '3306', 'db136s1ehvo1yn73', 'cxz307311SJK', 'fupai');
//全局定时器
Timer::add(1, function () use ($worker) {
global $db;
$time_now = time();
foreach ($worker->connections as $connection) {
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
$db->update('fp_light')->cols(array('status' => '2'))->where("number='$connection->uid'")->query();
}
}
});
// 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符
$inner_text_worker = new Worker('Text://114.215.223.17:5002');
$inner_text_worker->onMessage = function ($connection, $buffer) {
// $data数组格式,里面有uid,表示向那个uid的页面推送数据
$data = json_decode($buffer, true);
$uid = $data['uid'];
// $connection->send($uid);
// 通过workerman,向uid的页面推送数据
$ret = sendMessageByUid($uid, $data['percent']);
// 返回推送结果
$connection->send($ret ? 'ok' : 'fail');
// $connection->send($ret);
};
$inner_text_worker->listen();
};
//$worker->onConnect = function($connection)
//{
// echo "new connection from ip " . $connection->getRemoteIp() . "\n";
//};
//
//$worker->onClose = function($connection)
//{
// echo $connection->uid. "is exit" . "\n";
//};
// 当客户端发来数据时
$worker->onMessage = function ($connection, $data) use ($worker) {
echo bin2hex($data)."\n";
//记录最近的通讯信息
$connection->lastMessageTime = time();
//数据库资源
global $db;
//标记每个链接的uid
if (!isset($connection->uid)) {
// 没验证的话把第一个包当做uid(这里为了方便演示,没做真正的验证)
$str=substr(bin2hex($data), 0, 6);
$connection->uid =substr($str,4,2).substr($str,2,2).substr($str,0,2);
/* 保存uid到connection的映射,这样可以方便的通过uid查找connection,
* 实现针对特定uid推送数据
*/
$worker->uidConnections[$connection->uid] = $connection;
$re = $db->select('id')->from('fp_light')->where("number='$connection->uid'")->row();
if (!$re) {
$db->insert('fp_light')->cols(array(
'number' => $connection->uid,))->query();
} else {
$db->update('fp_light')->cols(array('status' => '1'))->where("number='$connection->uid'")->query();
}
}
//查询指令返回
if (substr(bin2hex($data),2,2)=='03'){
//设备状态
if (substr(bin2hex($data),6,2)=='01'){
$db->update('fp_light')->cols(array('status' => '1'))->where("number='$connection->uid'")->query();
}else if(substr(bin2hex($data),6,2)=='02'){
$db->update('fp_light')->cols(array('status' => '2'))->where("number='$connection->uid'")->query();
}else{
return false;
}
//点亮状态
if (substr(bin2hex($data),10,2)=='00'){
$db->update('fp_light')->cols(array('is_light' => '0'))->where("number='$connection->uid'")->query();
}else if(substr(bin2hex($data),10,2)=='01'){
$db->update('fp_light')->cols(array('is_light' => '1'))->where("number='$connection->uid'")->query();
}else{
return false;
}
//绑定状态
if (substr(bin2hex($data),12,2)=='00'){
$db->update('fp_light')->cols(array('is_blind' => '0'))->where("number='$connection->uid'")->query();
}else if(substr(bin2hex($data),12,2)=='01'){
$db->update('fp_light')->cols(array('is_blind' => '1'))->where("number='$connection->uid'")->query();
}else{
return false;
}
$name=substr(bin2hex($data),14);
$name=substr($name,0,strpos($name, '00'));
if(strlen($name)%2!=0){
$name=$name.'0';
}
$asc_arr = str_split(strtolower($name), 2);
$str = '';
for($i=0;$i<count($asc_arr);$i=$i+2){
$str.=chr(hexdec($asc_arr[$i])).chr(hexdec($asc_arr[$i+1]));
}
$str=mb_convert_encoding($str,'UTF-8','GB2312');
$db->update('fp_light')->cols(array('lighter' => "$str"))->where("number='$connection->uid'")->query();
}
//控制指令返回
if (substr(bin2hex($data),2,4)=='10'){
$re = $db->select('id')->from('fp_light')->where("number='$connection->uid'")->row();
if (substr(bin2hex($data),0,12)==$re['addr'].'1000000010'){
echo 'success';
}else{
echo 'false';
}
}
};
// 针对uid推送数据
function sendMessageByUid($uid, $message)
{
global $worker;
if (isset($worker->uidConnections[$uid])) {
$connection = $worker->uidConnections[$uid];
$str = '';
for ($i = 0; $i < strlen($message); $i += 2) {
$str .= chr(hexdec(substr($message, $i, 2)));
}
$connection->send($str);
return true;
}
// echo $worker->uidConnections[$uid];
// return $worker->uidConnections[$uid];
return false;
}
Worker::runAll();