1、无法执行多次回调
- 再次执行上一篇的案例
此种情况有点类似定时器,隔n秒执行一次的效果。如果要反复执行监听。需要加上”Event::PERSIST”
- 修改Event构造方法的参数
$event socket = new Event($eventBase,$resource,Event::READ|Event::PERSIST,’ accept ‘);
- 再次执行
2、嵌套问题
这里嵌套是指在回调方法里面,新增加”监听”。比如之前案例中,在回调方法”accept”,新增加可读or可写的监听
2.1、问题案例
在接收到新的socket链接时,针对该socket链接,监听其read操作
- 源码
- 执行结果
- 结果分析
首先是设置read监听不起作用,其次是整个服务都挂掉了。为什么?
答: 从accept函数中得知,新创建了一个event实例化对象,然后加入监听中。但是但离开accept函数后,根据变量的作用域,就被系统收回了。因此不起作用
2.2、修改方案
通过引入全局变量,保存变量。从而延长变量的生命周期
- 修改后的源码
<?php
/**
* Copyright (C) Iamasb
* @project : 3、workerman相关知识点
* @explain : Event操作socket
* @filename : 39、Event操作socket.php
* @author : xiaobei 2801616735@qq.com
*/
// 创建tcp
if (!($resource = socket_create(AF_INET,SOCK_STREAM,SOL_TCP))) {
echo “socket create is error”;
exit();
}
// 设置端口复用
if (!socket_set_option($resource, SOL_SOCKET, SO_REUSEADDR, 1)) {
echo ‘Unable to set option on socket: ‘. socket_strerror(socket_last_error()) . PHP_EOL;
exit;
}
// 绑定当前主机和端口
if (!socket_bind($resource,’0.0.0.0′,’1234′)) {
echo “socket bind is error”;
exit();
}
// 启动监听
if (!socket_listen($resource)) {
echo “socket listen is error”;
exit();
}
$GLOBALS[‘event’] = array();
$GLOBALS[‘eventBase’] = new EventBase();
$eventSocket = new Event($eventBase,$resource,Event::READ|Event::PERSIST,’accept’);
$eventSocket->add();
$GLOBALS[‘event’][(int)$resource] = $eventSocket;
$eventBase->loop();
function accept($socket)
{
echo “accept->”,PHP_EOL;
$client = socket_accept($socket);
socket_getpeername($client,$address,$port);
echo “new client->”,$address,’:’,$port,PHP_EOL;
$eventSocket = new Event($GLOBALS[‘eventBase’],$client,Event::READ|Event::PERSIST,’read’,$client);
if (!$eventSocket || !$eventSocket->add()) {
echo “error”,PHP_EOL;
}
$GLOBALS[‘event’][(int)$client] = $eventSocket;
return true;
}
function read($socket)
{
$string = socket_read($socket,1024);
echo “receive from client->”,trim($string),PHP_EOL;
$eventSocket = new Event($GLOBALS[‘eventBase’],$socket,Event::WRITE|Event::PERSIST,’write’,$socket);
if (!$eventSocket || !$eventSocket->add()) {
echo “error”,PHP_EOL;
}
$GLOBALS[‘event’][(int)$socket] = $eventSocket;
}
function write($socket)
{
echo “todo->Write”,PHP_EOL;
$string = “hello\n”;
socket_write($socket,$string,strlen($string));
socket_close($socket);
$GLOBALS[‘event’][(int)$socket]->del();
unset($GLOBALS[‘event’][(int)$socket]);
}
- 执行结果