Questions about event ->add() callback
$base = new EventBase();
$socket = stream_socket_server('tcp://0.0.0.0:9999', $errCode, $errMsg, \STREAM_SERVER_BIND |
\STREAM_SERVER_LISTEN, $content);
// first event callback success
$event = new Event($base, $socket, Event::READ|Event::PERSIST, function ($socket, $fd, $arg) {
$newSocket = stream_socket_accept($socket, 0, $remoteAddress);
// this Event callback not running
$event = new Event($arg[0], $newSocket, Event::READ|Event::PERSIST, function ($socket) {
$buff = fread($socket, 65535);
});
$event->add();
}, [&$base]);
$event->add();
$base->loop();
In the execution of the first closure, continue to add the second event, the second event callback is not executed,If the second event is encapsulated into a class, it can be executed normally
The following code can be written normally
class TcpConn
{
/**
* @var resource
*/
public $socket;
public function __construct($socket)
{
$this->socket = $socket;
Master::$globalEvent->add($this->socket, [$this, 'read'], 'stream_socket_accept');
}
public function read($socket)
{
$buff = fread($socket, 65536);
echo "客户端请求来了~\n";
echo $buff . "\n";
if (is_resource($socket)) {
fwrite($socket, "HTTP/1.1 200 OK\r\nAccept: application/json, text/plain, */*\r\nConnection: keep-alive\r\nContent-Length: 6\r\n\r\nhello~");
}
}
}
Master::$globalEvent = new EventLoop();
Master::$globalEvent->add($mainSocket, function ($sock) {
$newSocket = stream_socket_accept($sock, 0, $remoteAddress);
\stream_set_blocking($newSocket, 0);
// Compatible with hhvm
if (\function_exists('stream_set_read_buffer')) {
\stream_set_read_buffer($newSocket, 0);
}
echo 'remote address : ' . $remoteAddress . PHP_EOL;
new TcpConn($newSocket);
}, 'stream_socket_server');
Master::$globalEvent->loop();
echo "wait process exit~ pid = " . posix_getpid();
Comments (3)
-
reporter -
repo owner - changed status to on hold
The issue with the second callback is that the local
$event
variable is not preserved. When$event
goes out of the scope of the closure, it gets destroyed. As a result, the inner$event
is never triggered.You can avoid this by maintaining a reference to the event object somewhere outside of the inner scope, until it is no longer needed.
I hope this makes it a little bit more clear for you.
(I understand, that in an ideal world the PECL extension would magically handle this case :-))
-
reporter Thank you. I should know what happened
- Log in to comment
this is not a bug, Just my question about this code,I hope you can clear my mind