经过了简单的梳理workerman代码流程,发现了workerman架构对TCP\UDP与HTTP的协议用PHP重新实现了一遍,我把workerman的简单实现webServer的代码整理出来了,代码如下:
<?php
$_builtinTransports = array(
'ssl' => 'tcp'
);
$adderss="0.0.0.0:8011";
$transport = 'ssl';
$flags = $transport === 'udp' ? STREAM_SERVER_BIND : STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
$options = [
'http' => [
'method' => 'GET',
'header' => 'Accept-language: en\r\n'
]
];
$context = stream_context_create($options);
stream_context_set_option($context, 'socket', 'so_reuseport', 1);
$mainSocket = stream_socket_server($adderss,$errno,$errmsg,$flags,$context);
if(!$mainSocket) {
exit($errmsg);
}
if($transport === 'ssl')
{
stream_socket_enable_crypto($mainSocket,false);
}
if(function_exists('socket_import_stream') && $_builtinTransports[$transport] === 'tcp')
{
set_error_handler(function(){});
$socket = socket_import_stream($mainSocket);
socket_set_option($socket,SOL_SOCKET,SO_KEEPALIVE,1);
socket_set_option($socket,SOL_TCP,TCP_NODELAY,1);
restore_error_handler();
}
stream_set_blocking($mainSocket,false);
function acceptConnection($socket)
{
set_error_handler(function(){});
$new_socket = stream_socket_accept($socket, 0, $remote_address);
restore_error_handler();
stream_set_blocking($new_socket, 0);
stream_set_read_buffer($new_socket, 0);
$bytesRead = 0;
$recvBuffer = null;
$buffer = fread($new_socket, 65535);
$bytesRead+= strlen($buffer);
$recvBuffer .= $buffer;
$bufferArr = explode("\r\n",$buffer);
$headerStr = '';
if(!empty($bufferArr))
{
foreach($bufferArr as $header)
{
if(!empty($header))
{
$headerStr .= $header."\r\n";
}
}
}
$bytesRead += strlen($buffer);
$recvBuffer .= $buffer;
$sendBuffer = "hello word3333";
$body_len = \strlen($sendBuffer);
$sendBuffer = "HTTP/1.1 200 OK\r\nServer: xiaobo\r\n{$headerStr}Connection: keep-alive\r\nContent-Type: text/html;charset=utf-8\r\nContent-Length: $body_len\r\n\r\n$sendBuffer";
$len = fwrite($new_socket, $sendBuffer);
fclose($new_socket);
}
while(1)
{
$fd_key = (int)$mainSocket;
$read[$fd_key] = $mainSocket;
$write[$fd_key] = $mainSocket;
$except = [];
$allExcept[$fd_key][1] = $mainSocket;
$ret = false;
@stream_select($read, $write, $except, 0, 15);
foreach($read as $fd)
{
$fd_key = (int)$fd;
if(isset($allExcept[$fd_key][1]))
{
var_dump($fd_key);
acceptConnection($allExcept[$fd_key][1]);
}
}
}
?然后执行php webServer.php 效果如下图:
?
|