- changed status to resolved
php80
Issue #66
resolved
[root@6faaf20f5253 lumen-template]# php80 -v
PHP 8.0.3 (cli) (built: Mar 2 2021 16:37:06) ( NTS gcc x86_64 )
Copyright (c) The PHP Group
Zend Engine v4.0.3, Copyright (c) Zend Technologies
with Zend OPcache v8.0.3, Copyright (c), by Zend Technologies
[root@6faaf20f5253 lumen-template]# php80 --ri event
event
Event support => enabled
Sockets support => enabled
Debug support => disabled
Extra functionality support including HTTP, DNS, and RPC => enabled
OpenSSL support => enabled
Thread safety support => disabled
Extension version => 3.0.2r1
libevent2 headers version => 2.0.21-stable
[root@6faaf20f5253 swoole-test]# php80 epoll-server.php 5005
Segmentation fault
<?php
/**
* Created by Ling.
* Created on 2021/3/19 15:32
* @email: L_ing1992@163.com
*/
set_time_limit(0);
if ($argc != 2) // 判断 指令 参数个数
{
printf("usage: php epoll-server.php port\n");
return -1;
}
$eventSupportedMethods = Event::getSupportedMethods();
if (!in_array('epoll', $eventSupportedMethods)) {
die(' system not support epoll !!!');
}
$context = stream_context_create();
// 无法确下面设置是否生效 !
stream_context_set_option($context, 'socket', 'SO_REUSEADDR', true);
stream_context_set_option($context, 'socket', 'SO_KEEPALIVE', true);
//$flags 默认值为: STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
//$streamServerSocket = stream_socket_server('tcp://0.0.0.0:' . $argv[1], $errno, $errStr, context: $context); // php 80
$streamServerSocket = stream_socket_server('tcp://0.0.0.0:' . $argv[1], $errno, $errStr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context);
if ($streamServerSocket === false) {
die('stream_socket_server() failed !!!');
}
stream_set_blocking($streamServerSocket, false);
$eventConfig = new EventConfig();
foreach ($eventSupportedMethods as $method) { // 设置只使用 epoll方式
if ($method === 'epoll') continue;
$eventConfig->avoidMethod($method);
}
$eventBase = new EventBase($eventConfig);
$clientSockets = []; // 存储所有 socket
$clientSocketEvents = []; // 存储所有 Event
// 将socket绑定事件
// callback回调 static void event_cb(evutil_socket_t fd, short what, void *arg) 最后一个参数引用 __construct() 的最后一个参数
// public function __construct(EventBase $base, $fd, int $what, callable $cb, $arg = null)
$socketEvent = new Event($eventBase, $streamServerSocket, Event::READ | Event::PERSIST, function ($fd, int $what, EventBase $arg) use (&$clientSockets, &$clientSocketEvents) {
if ($what !== Event::READ) {
echo '不是 读事件(有设备连上) !!!';
return;
}
$clientSocket = stream_socket_accept($fd);
if ($clientSocket === false) {
echo 'stream_socket_accept() failed !!! ' . PHP_EOL;
return;
}
stream_set_blocking($fd, false);
//获取客户端IP地址
echo "client addr: " . stream_socket_get_name($clientSocket, true) . "\n";
$clientSockets[intval($clientSocket)] = $clientSocket; // 持久化 socket
$clientSocketEvent = new Event($arg, $clientSocket, Event::READ | Event::PERSIST, function ($fd, $what, $arg) use (&$clientSocketEvent, &$clientSockets, &$clientSocketEvents) {
if ($what !== Event::READ) {
echo '不是 读事件(有数据写入、设备断开) !!!';
return;
}
$buff = fread($fd, 1024);
if ($buff === false || $buff === '') {
echo "client closed !! " . intval($fd) . PHP_EOL;
echo "client addr: " . stream_socket_get_name($fd, true) . "\n";
// 清理、释放资源
fclose($fd);
unset($clientSockets[intval($fd)]);
$clientSocketEvent->del();
unset($clientSocketEvents[intval($fd)]);
return;
}
echo "recv:" . $buff . "\n";
fwrite($fd, $buff);
});
$clientSocketEvent->add();
$clientSocketEvents[intval($clientSocket)] = $clientSocketEvent; // 持久化 event
}, $eventBase);
// SIGINT 监听 ctrl + c 信号
$signalEvent = new Event($eventBase, SIGINT, Event::SIGNAL, function () use ($eventBase) {
echo 'event exit !!' . PHP_EOL;
$eventBase->exit(0); // ctrl + c 退出事件loop
});
$socketEvent->add();
$signalEvent->add();
// EventBase::LOOP_ONCE 阻塞直到libevent第一个活动事件的回调事件完成,然后在所有活动事件退出
// EventBase::LOOP_NONBLOCK 不要阻塞:查看哪些事件现在已经准备好,运行最高优先级的回调,然后退出
// 0 根据Event 执行事件
$eventBase->loop(0);
// 没有事件后 退出
fclose($streamServerSocket);
echo 'exit ' . PHP_EOL;
Comments (2)
-
repo owner -
repo owner Fixed in event-3.0.3
- Log in to comment
Fixed
#66: Segmentation fault when calling EventConfig::avoidMethod() in PHP 8→ <<cset ef42759e8c07>>