准备:
编译swoole的php扩展
开始:
建立tcp服务:
$server = new swoole_server('0.0.0.0',9502);
$server->set([
//这里用keepalive比用心跳检测要好,这里设置的心跳检测还要在客户端定时
//发送一段数据给服务器,做心跳校验,如果用keepalive的话就不需要再客户
//做手脚,keepalive是socket系统底层检测连接的,不需要应用层关心。
'heartbeat_check_interval' => 20,//心跳检测间隔时间(秒)
'heartbeat_idle_time' => 60*60,//client 未响应超时时间(秒)
'daemonize' => true,//守护进程
'worker_num'=>2,//同时工作的进程数量
'task_worker_num'=>10,//task数量(执行耗时任务)
'log_file' => '/Swoole/ws.log'
]);
监听连接
/**
* 连接事件监听
*/
$server->on('Connect',function($server,$fd){
echo "tcp connect($fd) +1 \n";
});
监听断开连接
/**
* 监听连接断开事件
*/
$server->on('Close',function ($server,$fd){
echo "close tcp connect($fd) -1 \n";
});
监听消息接收事件
/**
* 监听获取消息事件
*/
$server->on('Receive',function ($server,$fd,$fromId,$data){
echo "onReceiver data: $data \n";
$server->task($data);
});
监听task任务事件
//耗时长的程序应该在此处执行
$server->on('Task',function ($server,$task_id,$from_id,$data){
echo "task is finished \n";
// **数据库连接池**
static $link = null;
if($link == null){
$link = mysqli_connect("localhost","root","airlink8577","airlink_new");
}
if(!$link){
$link = null;
$server->finish("ERR:".mysqli_error($link));
return ;
}
$server->finish("OK:");
});
任务完成监听事件(与task成对存在)
$server->on("finish",function ($server,$task_id,$data){
echo "finish task $data \n";
});
连接池(redis)
//多进程之间不能共享数据,否则会出现tak使用的数据的来源不确定是哪一个fd
$server->on("WorkerStart",function ($serv,$work_id){
$redis = new Redis();
$redis->connect("127.0.0.1",6379);
$serv->redis = $redis;
//redis的连接与数据库连接不同,redis可以建立多个连接而不影响其性能,mysql的连接数量增加会影响数据库的性能,所以这里限制mysql的连接数量,通过复用数据库的连接来提高数据库的性能
});
数据库断线重连
socket连接的server端是常驻内存的,mysql连接在一段时间之内如果没有出现数据传输的情况会导致该连接与数据库断开,再次使用该连接的时候会导致报错,使用断线重连,在出现连接错误的情况下重新建立连接
/**
* @return mysqli mysql重连
*/
function reconnectMysql(){
$link = mysqli_connect("localhost","user","pwd","db");
return $link;
}
function sqlQuery($sql,&$link){//mysql 断线重连机制
if(!$link->query($sql)){
var_dump(mysqli_error($link));
if(mysqli_errno($link)=='2006'||mysqli_errno($link)=='2013'){
$link = reconnectMysql();
sqlQuery($sql,$link);
}
}
}
数据库连接等待超时时间设置:
mysql> show variables like '%timeout%'; //查看超时时间的设置
set interactive_timeout=604800; //修改超时时间
set wait_timeout=604800; //修改超时时间设置(主要改这个)
基础知识参考:
1、socket;
2、进程和线程优缺点;
3、进程间通信,管道通信;
4、进程间通信,共享内存;