服务启动前事件
function beforeWorkerStart(\swoole_server $server);
在执行beforeWorkerStart事件时,框架已经完成的工作有:
- frameInitialize 事件内的全部事务
- frameInitialized 事件内的全部事务
- 错误处理函数的注册
- swoole_http_server对象创建,且设置了启动参数。(未启动)
在该回调事件内,依旧可以进行一些全局设置和对象创建,同时可以对Swoole Server进行一些个性化的需求挖掘。
注意,此事件有别与框架初始化后事件,beforeWorkerStart仅在执行了服务启动才会被执行。
例如为Swoole Http Server添加web Socket支持
$server->on("message",function (\swoole_websocket_server $server, \swoole_websocket_frame $frame){
Logger::getInstance()->console("receive data".$frame->data);
$server->push($frame->fd,"you say ".$frame->data);
});
$server->on("handshake",function (\swoole_http_request $request, \swoole_http_response $response){
Logger::getInstance()->console("handshake");
//自定定握手规则,没有设置则用系统内置的(只支持version:13的)
if (!isset($request->header['sec-websocket-key']))
{
//'Bad protocol implementation: it is not RFC6455.'
$response->end();
return false;
}
if (0 === preg_match('#^[+/0-9A-Za-z]{21}[AQgw]==$#', $request->header['sec-websocket-key'])
|| 16 !== strlen(base64_decode($request->header['sec-websocket-key']))
)
{
//Header Sec-WebSocket-Key is illegal;
$response->end();
return false;
}
$key = base64_encode(sha1($request->header['sec-websocket-key']
. '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
true));
$headers = array(
'Upgrade' => 'websocket',
'Connection' => 'Upgrade',
'Sec-WebSocket-Accept' => $key,
'Sec-WebSocket-Version' => '13',
'KeepAlive' => 'off',
);
foreach ($headers as $key => $val)
{
$response->header($key, $val);
}
$response->status(101);
$response->end();
});
$server->on("close",function ($ser,$fd){
Logger::getInstance()->console("client {$fd} close");
});
例如监听TCP链接
$listener = $server->addlistener("0.0.0.0",9502,SWOOLE_TCP);
//混合监听tcp时 要重新设置包解析规则 才不会被HTTP覆盖,且端口不能与HTTP SERVER一致 HTTP本身就是TCP
$listener->set(array(
"open_eof_check"=>false,
"package_max_length"=>2048,
));
$listener->on("connect",function(\swoole_server $server,$fd){
Logger::getInstance()->console("client connect");
});
$listener->on("receive",function(\swoole_server $server,$fd,$from_id,$data){
Logger::getInstance()->console("received connect");
$server->send($fd,"swoole ".$data);
$server->close($fd);
});
$listener->on("close",function (\swoole_server $server,$fd){
Logger::getInstance()->console("client close");
});
例如监听UDP链接
$udp = $server->addlistener("0.0.0.0",9503,SWOOLE_UDP);
//udp 请勿用receive事件
$udp->on('packet',function(\swoole_server $server, $data,$clientInfo){
var_dump($data);
});
使用Event Loop监听UDP
$listener = stream_socket_server(
"udp://0.0.0.0:9504",
$error,
$errMsg,
STREAM_SERVER_BIND
);
if($errMsg){
throw new \Exception("cluster server bind error on msg :{$errMsg}");
}else{
//加入event loop
swoole_event_add($listener,function($listener){
$data = stream_socket_recvfrom($listener,9504,0,$client);
var_dump($data);
stream_socket_sendto($listener,"hello",0,$client());
});
}
注意:TCP同理。
例如添加自定义Process进程
$server->addProcess(new \swoole_process(function (){
while (1){
/*
* for example,you can set a redis,kafka or rabbitMQ client
* here,and read the message queue in blocking mode
*/
sleep(1);
Logger::getInstance()->console("my process run");
}
})
);