使用Thinkphp5.0框架
服务端:
<?php
namespace app\Console;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Cache;
/**
* swoole异步
*/
class Async extends Command
{
private $serv;
public $agent = [
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
"Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
];
// 命令行配置函数
protected function configure()
{
// setName 设置命令行名称
// setDescription 设置命令行描述
$this->setName('task:start')->setDescription('Start Task Server!');
}
// thinkphp执行
protected function execute(Input $input, Output $output)
{
$this->serv = new \swoole_server("127.0.0.1", 9501);
$this->serv->set(array(
'worker_num' => 1,
'daemonize' => false, // 守护进程,开启后,关闭SSH面也可进行
'log_file' => '/home/wwwroot/swoole_task.log',
'task_worker_num' => 500 // task进程数量
));
$this->serv->on('Start', array($this, 'onStart'));
$this->serv->on('Connect', array($this, 'onConnect'));
$this->serv->on('Receive', array($this, 'onReceive'));
$this->serv->on('Close', array($this, 'onClose'));
$this->serv->on('Task', array($this, 'onTask'));
$this->serv->on('Finish', array($this, 'onFinish'));
$this->serv->start();
}
// 收到信息时执行
public function onReceive( \swoole_server $serv, $fd, $from_id, $data )
{
echo "收到数据" . PHP_EOL;
$data = json_decode($data, true);
$user = Db::name('wx_user')->where('subscribe', 1)->column('openid');
foreach ($user as $key => $value) {
$info = [
"touser" => $value,
"template_id" => "NxkCFDez01L72afWIQjzyKDXgTMBOwFTw0ZZt6usQtQ",
"url" => 'http://www.xxx.com/index',
"topcolor" => "#000000",
"data"=>[
"first"=> [
"value" => '双十一活动来了!',
"color" =>"#000000"
],
"keyword1"=>[
"value"=> '【双十一钜惠】秒杀!超低价!立减420元!',
"color"=>"#FF0033"
],
"keyword2"=>[
"value"=> '尊敬的用户',
"color"=>"#000000"
],
"remark"=>[
"value"=> '点击这里了解更多>>>',
"color"=>"#0066FF"
],
],
];
$info = json_encode($info);
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$data['access_token'];
// 投递异步任务
$serv->task([
'url' => $url,
'info' => $info
]);
}
}
// 处理异步任务
public function onTask($serv, $task_id, $from_id, $data)
{
echo "开始处理异步" . PHP_EOL;
$res = httpRequest($data['url'], $data['info']);
var_dump($res);
$serv->finish('请求回调方法');
}
// 异步任务完成通知回调
public function onFinish($serv, $task_id, $data) {
echo "完成回调". date("Y-m-d H:i:s") .':'.$data;
}
// 主进程启动时回调函数
public function onStart( $serv ) {
echo "服务端启动:" . date("Y-m-d H:i:s") . PHP_EOL;
}
// 建立连接
public function onConnect( $serv, $fd, $from_id ) {
echo "客户端连接成功:". date("Y-m-d H:i:s") . PHP_EOL;
}
// 关闭连时回调函数
public function onClose( $serv, $fd, $from_id ) {
echo "客户端关闭连接:". date("Y-m-d H:i:s") . PHP_EOL;
}
}
服务端中命名空间的定义,以及引入think下的类,是方便CLI启动,点击查看参考文档,服务端需要在命令行中启动,这里要在application同级目录中,使用php think task:start 命令启动。如图:
客户端:
/**
* 请求服务端
*/
public function client($value='')
{
$client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
$ret = $client->connect("127.0.0.1", 9501);
// 可传递参数,这里获取缓存好的access_token
$sendData = [
'access_token' => getAccessToken()
];
if (empty($ret)) {
shell_exec("echo '连接swoole服务器失败'>>");
} else {
$res = $client->send(json_encode($sendData));
var_dump($ret);
}
}
客户端可以在控制器中定义,成功开启服务端后,请求该接口即可。
扩展:
netstat -anp | grep 9501 查看9501端口占用情况
kill 23566 关闭占用端口进程
安装swoole
Linux查看swoole是否安装成功
PHP swoole协程框架
异步执行任务Task
Swoole初探:环境搭建与入门案例
PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
Swoole Task 的应用
Swoole扩展中socket客户端的使用