服务启动前事件

  1. function beforeWorkerStart(\swoole_server $server);

在执行beforeWorkerStart事件时,框架已经完成的工作有:

  • frameInitialize 事件内的全部事务
  • frameInitialized 事件内的全部事务
  • 错误处理函数的注册
  • swoole_http_server对象创建,且设置了启动参数。(未启动)

在该回调事件内,依旧可以进行一些全局设置和对象创建,同时可以对Swoole Server进行一些个性化的需求挖掘。

注意,此事件有别与框架初始化后事件,beforeWorkerStart仅在执行了服务启动才会被执行。

例如为Swoole Http Server添加web Socket支持

  1. $server->on("message",function (\swoole_websocket_server $server, \swoole_websocket_frame $frame){
  2. Logger::getInstance()->console("receive data".$frame->data);
  3. $server->push($frame->fd,"you say ".$frame->data);
  4. });
  5. $server->on("handshake",function (\swoole_http_request $request, \swoole_http_response $response){
  6. Logger::getInstance()->console("handshake");
  7. //自定定握手规则,没有设置则用系统内置的(只支持version:13的)
  8. if (!isset($request->header['sec-websocket-key']))
  9. {
  10. //'Bad protocol implementation: it is not RFC6455.'
  11. $response->end();
  12. return false;
  13. }
  14. if (0 === preg_match('#^[+/0-9A-Za-z]{21}[AQgw]==$#', $request->header['sec-websocket-key'])
  15. || 16 !== strlen(base64_decode($request->header['sec-websocket-key']))
  16. )
  17. {
  18. //Header Sec-WebSocket-Key is illegal;
  19. $response->end();
  20. return false;
  21. }
  22. $key = base64_encode(sha1($request->header['sec-websocket-key']
  23. . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
  24. true));
  25. $headers = array(
  26. 'Upgrade' => 'websocket',
  27. 'Connection' => 'Upgrade',
  28. 'Sec-WebSocket-Accept' => $key,
  29. 'Sec-WebSocket-Version' => '13',
  30. 'KeepAlive' => 'off',
  31. );
  32. foreach ($headers as $key => $val)
  33. {
  34. $response->header($key, $val);
  35. }
  36. $response->status(101);
  37. $response->end();
  38. });
  39. $server->on("close",function ($ser,$fd){
  40. Logger::getInstance()->console("client {$fd} close");
  41. });

例如监听TCP链接

  1. $listener = $server->addlistener("0.0.0.0",9502,SWOOLE_TCP);
  2. //混合监听tcp时 要重新设置包解析规则 才不会被HTTP覆盖,且端口不能与HTTP SERVER一致 HTTP本身就是TCP
  3. $listener->set(array(
  4. "open_eof_check"=>false,
  5. "package_max_length"=>2048,
  6. ));
  7. $listener->on("connect",function(\swoole_server $server,$fd){
  8. Logger::getInstance()->console("client connect");
  9. });
  10. $listener->on("receive",function(\swoole_server $server,$fd,$from_id,$data){
  11. Logger::getInstance()->console("received connect");
  12. $server->send($fd,"swoole ".$data);
  13. $server->close($fd);
  14. });
  15. $listener->on("close",function (\swoole_server $server,$fd){
  16. Logger::getInstance()->console("client close");
  17. });

例如监听UDP链接

  1. $udp = $server->addlistener("0.0.0.0",9503,SWOOLE_UDP);
  2. //udp 请勿用receive事件
  3. $udp->on('packet',function(\swoole_server $server, $data,$clientInfo){
  4. var_dump($data);
  5. });

使用Event Loop监听UDP

  1. $listener = stream_socket_server(
  2. "udp://0.0.0.0:9504",
  3. $error,
  4. $errMsg,
  5. STREAM_SERVER_BIND
  6. );
  7. if($errMsg){
  8. throw new \Exception("cluster server bind error on msg :{$errMsg}");
  9. }else{
  10. //加入event loop
  11. swoole_event_add($listener,function($listener){
  12. $data = stream_socket_recvfrom($listener,9504,0,$client);
  13. var_dump($data);
  14. stream_socket_sendto($listener,"hello",0,$client());
  15. });
  16. }

注意:TCP同理。

例如添加自定义Process进程

  1. $server->addProcess(new \swoole_process(function (){
  2. while (1){
  3. /*
  4. * for example,you can set a redis,kafka or rabbitMQ client
  5. * here,and read the message queue in blocking mode
  6. */
  7. sleep(1);
  8. Logger::getInstance()->console("my process run");
  9. }
  10. })
  11. );