linux的基础命令:
1.netstat -anp|grep 9501 查看9051端口;
2.telnet 127.0.0.1 9501 监听9501端口;
3.kill -9 XXX 强制杀死进程;
一、swoole_server
server(服务端):
<?php
//创建Server对象,监听 127.0.0.1:9501端口
$serv = new \swoole_server("127.0.0.1", 9501);
$serv->set([
'worker_num' => 4, //进程数 是cpu的1-4倍
]);
/*
* $fd 客户端连接的唯一标识
* $reactor_id 线程id
*/
//监听连接进入事件
$serv->on('connect', function ($serv, $fd,$reactor_id) {
echo "Client:{$reactor_id}--{$fd} Connect.\n";
});
//监听数据接收事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
$serv->send($fd, "Server:{$reactor_id}--{$fd} ".$data);
});
//监听连接关闭事件
$serv->on('close', function ($serv, $fd) {
echo "Client: Close.\n";
});
//启动服务器
$serv->start();
?>
client(客户端):
<?php
//连接swoole 服务
$cli = new swoole_client(SWOOLE_TCP);
//判断连接状态(同步连接模式)
if ($cli->connect('127.0.0.1', 9501)) {
echo "成功";
} else {
echo "失败";
}
//写入CLI提示信息,
fwrite(STDOUT, '请输入你得名字:');
//获取用户输入数据
$name = trim(fgets(STDIN));
//发送消息给server
$cli->send($name);
//接收来自server的消息
$rel=$cli->recv();
echo $rel;
二、Hppt_swoole
server:
<?php
//连接一个新的服务 0.0.0.0是监听所有的服务
$cli=new swoole_http_server("0.0.0.0",9501);
$cli->on('request',function($request,$response){
//使用write分段发送数据后,end方法将不接受任何参数
$response->write(json_encode($request->get));
//发送Http响应体,并结束请求处理。
$response->end('ssss'.json_encode($request->get));
});
//启动
$cli->start();
?>
结果:
访问http://127.0.0.1:9501?name=1,html输出是{"name":"111111"},而非ssss.{"name":"111111"};
server中的set:
//连接设置
$cli->set([
//类似于重定向
'enable_static_handler'=>true,
'docment_root'=>"/www/wwwroot/laravel/public/swoole/data",
]);
三、Web_socket
1.web_socket面向过程的写法:
<?php
//创建websocket服务器对象,监听0.0.0.0:9501端口
$server = new swoole_websocket_server("0.0.0.0", 9501);
//监听WebSocket连接打开事件
$server->on('open', function ($server, $request) {
//push是往前端传递的方法
$server->push($request->fd,'小子,你连接成功了');
//所有输出的命令是直接输出于终端
// var_dump("你已经开启服务:{$request->fd}\n");
});
//监听WebSocket消息事件
$server->on('message', function ($server, $frame) {
// var_dump("新的消息:{$frame->data}\n");
$server->push($frame->fd, "{$frame->data}");
});
//监听WebSocket连接关闭事件
$server->on('close', function ($ser, $fd) {
// $server->push($fd,'我睡呀,你玩吧!');
var_dump("你好,我的{$fd}\n");
});
$server->start();
2.web_socket面向对象的写法:
<?php
/**
* socket面向对象的编译
*
*/
class Ws
{
CONST HOST='0.0.0.0';
CONST PORT='9501';
public $ws=null;
function __construct()
{
$this->ws=new swoole_websocket_server(self::HOST,self::PORT);
$this->ws->on('open',[$this,'onopen']);
$this->ws->on('message',[$this,'onmessage']);
$this->ws->on('close',[$this,'onclose']);
$this->ws->start();
}
/**
监听开启事件的回调
*/
function onopen($server, $request)
{
$server->push($request->fd,'小子,面向对象你也连接成功了');
}
/**
监听接收事件的回调
*/
function onmessage($server, $frame)
{
$server->push($frame->fd, "{$frame->data}");
}
/**
监听关闭事件的回调
*/
function onclose($ser, $fd)
{
var_dump("你好,我的{$fd}\n");
}
}
$new=new Ws();
web_sockethtml的写法:
<!DOCTYPE html>
<html>
<head>
<title>我是来测试的</title>
</head>
<body>
<h1>我是来测试的11111111111</h1>
<script type="text/javascript">
//连接服务
var wsServer = 'ws://140.82.0.240:9501';
//实例化
var websocket = new WebSocket(wsServer);
//监听开启事件(只负责监听,没有实际的开启作用)
websocket.onopen = function (evt) {
websocket.send('我是来搞事的!!!');
// console.log("连接成功html");
};
//消息
websocket.onmessage = function (evt) {
//监听消息后,直接给服务器传递消息
console.log('来自server的最新消息: ' + evt.data);
};
//关闭事件
websocket.onclose = function (evt) {
console.log("我关闭了html");
};
//报错
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
</script>
</body>
</html>
3.task
使用场景
- 执行耗时的操作(发送邮件 广播等)
注意:
- 投递异步任务之后程序会
继续往下执行
,不会等待任务执行完后再继续向下执行
<?php
/**
* socket面向对象的编译
*
*/
class Ws
{
CONST HOST='0.0.0.0';
CONST PORT='9501';
public $ws=null;
function __construct()
{
$this->ws=new swoole_websocket_server(self::HOST,self::PORT);
$this->ws->set([
//启动task必须要设置其数量
'task_worker_num'=>2,
]);
$this->ws->on('open',[$this,'onopen']);
$this->ws->on('message',[$this,'onmessage']);
$this->ws->on('task',[$this,'onTask']);
$this->ws->on('finish',[$this,'onFinish']);
$this->ws->on('close',[$this,'onclose']);
$this->ws->start();
}
/**
监听开启事件的回调
*/
function onopen($server, $request)
{
$server->push($request->fd,'小子,面向对象你也连接成功了');
}
/**
监听接收事件的回调
*/
function onmessage($server, $frame)
{
//投递异步任务task,非阻塞,使用必须设置Server的onTask和onFinish事件回调函数
$data=[
'name'=>'你大爷的',
'id'=>$frame->fd,
];
$server->task($data);
$server->push($frame->fd, "{$frame->data}");
}
/**
监听关闭事件的回调
*/
function onclose($ser, $fd)
{
print_r("你好,我的{$fd}\n");
}
/**
* $serv 服务
* $task_id 任务ID,由swoole扩展内自动生成,用于区分不同的任务
* $src_worker_id $task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同
* $data 是任务的内容
*/
function onTask($serv,$task_id,$src_worker_id,$data)
{
//在终端输出
print_r($data).'/n';
//执行耗时任务
sleep(10);
//回调于onFinish
return '你二大爷的';
}
/**
* $task_id 是任务的ID
* $data 是任务处理的结果内容
*/
function onFinish($serv,$task_id,$data)
{
print_r($data).'/n';
}
}
$new=new Ws();
html测试结果:
CLI返回结果:
四、异步IO
1.毫秒定时器
/**
监听接收事件的回调
*/
function onmessage($server, $frame)
{
//投递异步任务task,非阻塞,使用必须设置Server的onTask和onFinish事件回调函数
$data=[
'name'=>'你大爷的',
'id'=>$frame->fd,
];
$server->task($data);
//异步毫秒定时器
//每3秒循环执行
swoole_timer_tick(3000,function() use($server, $frame){
$server->push($frame->fd, "我是循环的");
});
//3秒后执行一次
swoole_timer_after(3000,function() use($server, $frame){
$server->push($frame->fd, "我就只有一次");
});
$server->push($frame->fd, "{$frame->data}");
}
执行结果:
2.异步读取文件
<?php
/**
* 异步读取文件
* __DIR__ 当前文件的路径(php魔术方法)
* PHP_EOL 不同系统对应不同的换行符
*/
$res=swoole_async_readfile(__DIR__.'/1.txt', function($filename,$fileContent){
echo 'name:'.$filename.PHP_EOL;
echo 'content:'.$fileContent.PHP_EOL;
});
var_dump($res);
echo 123;
执行结果:先执行同步,后执行异步
3.1异步写入文件
<?php
/**
* 异步写入
*/
$content='你大爷的,现在几点了?'.date('H:i:s').PHP_EOL;
swoole_async_writefile(__DIR__.'/1.log',$content,function($filename){
echo '写入成功!'.PHP_EOL;
},FILE_APPEND);
echo '我是123'.PHP_EOL;
执行结果:先执行同步,后执行异步
3.2异步写入html信息
/**
* 异步获取url信息并写入
*
*/
//连接一个新的服务 0.0.0.0是监听所有的服务
$cli=new swoole_http_server("0.0.0.0",9501);
$cli->on('request',function($request,$response){
$content=[
'time:'=>date('H:i:s'),
'get:'=>$request->get,
'post:'=>$request->post,
'header:'=>$request->header,
];
swoole_async_writefile(__DIR__.'/access.log',json_encode($content).PHP_EOL,function($filename){
echo '写入成功!'.PHP_EOL;
},FILE_APPEND);
$response->end('ssss'.json_encode($request->get));
});
//启动
$cli->start();
结果:
访问http://127.0.0.1:9501?name=1,html输出是ssss{"name":"111111"},生成了access.log文件;
4.异步操作mysql
<?php
/**
* 异步sql的操作
*/
class Mysql
{
public $sql=null;
public $config=null;
function __construct()
{
//实例化一个数据库的连接
$this->sql= new swoole_mysql;
//配置信息
$this->config=[
'host' => '140.82.0.240',
'port' => 3306,
'user' => 'weibao',
'password' => 'aCHZhsKTzrZpR',
'database' => 'weibao',
'charset' => 'utf8', //指定字符集
'timeout' => 2, // 可选:连接超时时间(非查询超时时间),默认为SW_MYSQL_CONNECT_TIMEOUT(1.0)
];
}
public function select($id,$table)
{
//连接数据库
$this->sql->connect($this->config,function($db,$result) use($id,$table){
//连接失败,打印错误信息
if ($result == false) {
echo '连接失败'.PHP_EOL;
echo $db->connect_errno.PHP_EOL;
echo $db->connect_error.PHP_EOL;
die;
}
//编写sql
$sql='select * from hy_'.$table.' where '.$table.'_id =' .$id;
// echo $sql.PHP_EOL;
//执行sql语句
/**
* 执行失败,$result为false,读取$link对象的error属性获得错误信息,errno属性获得错误码
* 执行成功,SQL为非查询语句,$result为true,读取$link对象的affected_rows属性获得影响的行数,insert_id属性获得Insert操作的自增ID
* 执行成功,SQL为查询语句,$result为结果数组
*/
$db->query($sql,function($link,$result){
if ($result === false) {
echo $link->error.PHP_EOL;
}elseif ($result === true) {
echo '成功了!'.PHP_EOL;
}else{
print_r($result).PHP_EOL;
}
//$link就是$db
// print_r($link);
//关闭连接
$link->close();
});
});
return true;
}
}
$res=new Mysql();
$select=$res->select(1,'ads');
var_dump($select).PHP_EOL;
echo "start".PHP_EOL;
执行结果:先执行同步,后执行异步
5.异步redis
swoole使用redis的前置条件
redis
服务hiredis
库- 编译
swoole
需要加入-enable-async-redis
编译安装hiredis
使用Redis
客户端,需要安装hiredis
库,下载hiredis
源码后,执行
make -j
sudo make install
sudo ldconfig
启用异步Redis客户端
编译swoole
时,在configure
指令中加入--enable-async-redis
[root@izwz93ee3z8wdxsujiec2oz swoole]# ./configure --with-php-config=/usr/local/php/bin/php-config --enable-async-redis
make clean
make -j
sudo make install
查看PHP
的swoole
扩展:php -m
查看hiredis
是否编译安装成功:php --ri swoole
代码测试
<?php
//实例化
$redisClient = new Swoole\Redis;// Swoole\Redis
//配置信息并连接
$redisClient->connect('127.0.0.1', 6379, function(swoole_redis $redis, $result) {
echo "connect:".PHP_EOL;
if ($result === false) {
//打出错误的信息
var_dump($redis->errMsg);
die;
}
var_dump($result);
$redis->get('aa', function(swoole_redis $redisClient, $result) {
var_dump($result);
$redisClient->close();
});
});
echo "start".PHP_EOL;
结果返回: