php 非阻塞mysql_php非阻塞服务器

{const ERROR = 0;const LOG = 1;const DEBUG = 2;private $aConfig = NULL;private $hSocket = NULL;private $aClients = array();private $iRunning = 0;private $iStartTime = 0;private $iLastActivity = 0;private static $aDefaults = array('main' => array('address' => 'localhost',

'port' => 15151,

'backlog' => 200,

'select_timeout' => 1,

'pid_file' => 'phpserver.pid'),

'verbosity' => array('echo_log' => 1,

'echo_debug' => 0,

'echo_errors' => 1,

'log_errors' => 1)

);public functiongetPidFile()

{return $this->aConfig['main']['pid_file'];

}private static function getName( $hSocket)

{return socket_getpeername( $hSocket, $sAddress, $iPort ) ? "$sAddress:$iPort" : "?????:???";

}private function log( $sMessage, $iType)

{$sTimeStamp = @strftime( '%c');if( $iType == self::ERROR )

{$aBacktrace = debug_backtrace();$aBacktrace = $aBacktrace[1];$sMessage = sprintf( '[%s] [E] %s%s%s [%d] : %s', $sTimeStamp, $aBacktrace['class'], $aBacktrace['type'], $aBacktrace['function'], $aBacktrace['line'], $sMessage);if( $this->aConfig['verbosity']['echo_errors'] )printf( "$sMessage\n");if( $this->aConfig['verbosity']['log_errors'] )error_log( $sMessage);

}else if( $iType == self::DEBUG && $this->aConfig['verbosity']['echo_debug'] )

{echo sprintf( '[%s] [D] : %s', $sTimeStamp, $sMessage )."\n";

}else if( $iType == self::LOG && $this->aConfig['verbosity']['echo_log'] )

{echo sprintf( '[%s] [L] : %s', $sTimeStamp, $sMessage )."\n";

}

}/** Handle clients here.*/

private function handleClientRequest( $hClient, $iClientIndex)

{/** ...*/

$this->disconnect( $iClientIndex);

}private function disconnect( $i)

{

socket_close($this->aClients[ $i] );$this->aClients[ $i ] = NULL;

}private function loadConfiguration( $sConfigFile)

{if( !is_file( $sConfigFile ) || !is_readable( $sConfigFile) )die( "Could not read $sConfigFile.\n");else if( !( $this->aConfig = parse_ini_file( $sConfigFile, TRUE) ) )die( "Could not parse $sConfigFile.\n");foreach( self::$aDefaults as $sSection => $aDefaultValues)

{if( !isset( $this->aConfig[ $sSection] ) )$this->aConfig[ $sSection ] = array();foreach( $aDefaultValues as $sName => $sValue)

{if( !isset( $this->aConfig[ $sSection ][ $sName] ) )$this->aConfig[ $sSection ][ $sName ] = $sValue;

}

}

}public function setConfig( $sSectionName, $sConfigName, $mValue)

{if( !isset( $this->aConfig[ $sSectionName] ) )$this->aConfig[ $sSectionName ] = array();$this->aConfig[ $sSectionName ][ $sConfigName ] = $mValue;

}public function __construct( $sConfigFile)

{$this->loadConfiguration( $sConfigFile);if( !( $this->hSocket = socket_create( AF_INET, SOCK_STREAM,SOL_TCP ) ) )$this->log( 'Could not create main socket ( '.socket_strerror( socket_last_error() ).' ).', self::ERROR );else if( socket_set_option( $this->hSocket, SOL_SOCKET, SO_REUSEADDR, 1 ) === FALSE)$this->log( 'Could not set SO_REUSEADDR flag ( '.socket_strerror( socket_last_error() ).' ).', self::ERROR );

}public functionstart()

{if( !socket_bind( $this->hSocket, $this->aConfig['main']['address'], $this->aConfig['main']['port'] ) )$this->log( 'Could not bind on '.$this->aConfig['main']['address'].':'.$this->aConfig['main']['port'].' ( '.socket_strerror( socket_last_error() ).' ).', self::ERROR );else if( !socket_listen( $this->hSocket, $this->aConfig['main']['backlog'] ) )$this->log( 'Could not put main socket in listening mode ( '.socket_strerror( socket_last_error() ).' ).', self::ERROR );else if( !socket_set_nonblock( $this->hSocket ) )$this->log( 'Could not set main socket in non-blocking mode ( '.socket_strerror( socket_last_error() ).' ).', self::ERROR );else{$this->iStartTime = time();$this->log( 'Server started on '.$this->aConfig['main']['address'].':'.$this->aConfig['main']['port'].' .', self::LOG);for(;;)

{$aRead = array_merge( array( $this->hSocket ), $this->aClients );if( socket_select( $aRead, $aWrite, $aExcept, $this->aConfig['main']['select_timeout'] ) )

{if( in_array( $this->hSocket, $aRead) )

{if( ( $hClient = @socket_accept( $this->hSocket ) ) )

{$this->aClients[ microtime(TRUE) ] = $hClient;$this->iLastActivity = time();$this->log( 'New incoming connection '.self::getName( $hClient ), self::DEBUG );

}else

$this->log( 'Could not accept a new connection ( '.socket_strerror( socket_last_error() ).' ).', self::ERROR );

}

}/** Search for readable clients.*/

foreach( $this->aClients as $i => $hClient)

{if( in_array( $hClient, $aRead) )

{$this->handleClientRequest( $hClient, $i);

}

}/** Remove closed connections.*/

$this->aClients = array_filter( $this->aClients );

}

}

}public function__destruct()

{if( $this->hSocket )

{$this->log( 'Shutting down ...', self::LOG);foreach( $this->aClients as $sId => $hClient)

{if( $hClient)

socket_close($hClient);

}

socket_close($this->hSocket );

}

@unlink( $this->getPidFile() );

}

}?>

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值