walkor 10 жил өмнө
parent
commit
fe4d14d079

+ 66 - 1
GatewayWorker/BusinessWorker.php

@@ -10,14 +10,38 @@ use \GatewayWorker\Lib\Store;
 use \GatewayWorker\Lib\Context;
 use \Event;
 
+/**
+ * 
+ * BusinessWorker 用于处理Gateway转发来的数据
+ * 
+ * @author walkor<walkor@workerman.net>
+ *
+ */
 class BusinessWorker extends Worker
 {
+    /**
+     * 如果连接gateway通讯端口失败,尝试重试多少次
+     * @var int
+     */
     const MAX_RETRY_COUNT = 5;
     
+    /**
+     * 保存与gateway的连接connection对象
+     * @var array
+     */
     public $gatewayConnections = array();
     
+    /**
+     * 连接失败gateway内部通讯地址
+     * @var array
+     */
     public $badGatewayAddress = array();
     
+    /**
+     * 构造函数
+     * @param string $socket_name
+     * @param array $context_option
+     */
     public function __construct($socket_name = '', $context_option = array())
     {
         $this->onWorkerStart = array($this, 'onWorkerStart');
@@ -26,6 +50,10 @@ class BusinessWorker extends Worker
         $this->_appInitPath = dirname($backrace[0]['file']);
     }
     
+    /**
+     * 当进程启动时一些初始化工作
+     * @return void
+     */
     protected function onWorkerStart()
     {
         Timer::add(1, array($this, 'checkGatewayConnections'));
@@ -33,13 +61,20 @@ class BusinessWorker extends Worker
         \GatewayWorker\Lib\Gateway::setBusinessWorker($this);
     }
     
+    /**
+     * 当gateway转发来数据时
+     * @param TcpConnection $connection
+     * @param mixed $data
+     */
     public function onGatewayMessage($connection, $data)
     {
+        // 上下文数据
         Context::$client_ip = $data['client_ip'];
         Context::$client_port = $data['client_port'];
         Context::$local_ip = $data['local_ip'];
         Context::$local_port = $data['local_port'];
         Context::$client_id = $data['client_id'];
+        // $_SERVER变量
         $_SERVER = array(
                 'REMOTE_ADDR' => Context::$client_ip,
                 'REMOTE_PORT' => Context::$client_port,
@@ -47,6 +82,7 @@ class BusinessWorker extends Worker
                 'GATEWAY_PORT'  => Context::$local_port,
                 'GATEWAY_CLIENT_ID' => Context::$client_id,
         );
+        // 尝试解析session
         if($data['ext_data'] != '')
         {
             $_SESSION = Context::sessionDecode($data['ext_data']);
@@ -59,6 +95,7 @@ class BusinessWorker extends Worker
         $session_str_copy = $data['ext_data'];
         $cmd = $data['cmd'];
     
+        // 尝试执行Event::onConnection、Event::onMessage、Event::onClose
         try{
             switch($cmd)
             {
@@ -79,6 +116,7 @@ class BusinessWorker extends Worker
             $this->log($msg);
         }
     
+        // 判断session是否被更改
         $session_str_now = $_SESSION !== null ? Context::sessionEncode($_SESSION) : '';
         if($session_str_copy != $session_str_now)
         {
@@ -88,11 +126,21 @@ class BusinessWorker extends Worker
         Context::clear();
     }
     
+    /**
+     * 当与Gateway的连接断开时触发
+     * @param TcpConnection $connection
+     * @return  void
+     */
     public function onClose($connection)
     {
         unset($this->gatewayConnections[$connection->remoteAddress]);
     }
-    
+
+    /**
+     * 检查gateway的通信端口是否都已经连
+     * 如果有未连接的端口,则尝试连接
+     * @return void
+     */
     public function checkGatewayConnections()
     {
         $key = 'GLOBAL_GATEWAY_ADDRESS';
@@ -115,17 +163,34 @@ class BusinessWorker extends Worker
         }
     }
     
+    /**
+     * 当连接上gateway的通讯端口时触发
+     * 将连接connection对象保存起来
+     * @param TcpConnection $connection
+     * @return void
+     */
     public function onConnectGateway($connection)
     {
         $this->gatewayConnections[$connection->remoteAddress] = $connection;
         unset($this->badGatewayAddress[$connection->remoteAddress]);
     }
     
+    /**
+     * 当与gateway的连接出现错误时触发
+     * @param TcpConnection $connection
+     * @param int $error_no
+     * @param string $error_msg
+     */
     public function onError($connection, $error_no, $error_msg)
     {
          $this->tryToDeleteGatewayAddress($connection->remoteAddress, $error_msg);
     }
     
+    /**
+     * 从存储中删除删除连不上的gateway通讯端口
+     * @param string $addr
+     * @param string $errstr
+     */
     public function tryToDeleteGatewayAddress($addr, $errstr)
     {
         $key = 'GLOBAL_GATEWAY_ADDRESS';

+ 147 - 7
GatewayWorker/Gateway.php

@@ -7,28 +7,81 @@ use \Workerman\Protocols\GatewayProtocol;
 use \GatewayWorker\Lib\Lock;
 use \GatewayWorker\Lib\Store;
 
+/**
+ * 
+ * Gateway,基于Worker开发
+ * 用于转发客户端的数据给Worker处理,以及转发Worker的数据给客户端
+ * 
+ * @author walkor<walkor@workerman.net>
+ *
+ */
 class Gateway extends Worker
 {
+    /**
+     * 本机ip
+     * @var 单机部署默认127.0.0.1,如果是分布式部署,需要设置成本机ip
+     */
     public $lanIp = '127.0.0.1';
     
+    /**
+     * gateway内部通讯起始端口,每个gateway实例应该都不同,步长1000
+     * @var int
+     */
     public $startPort = 2000;
     
+    /**
+     * 是否可以平滑重启,gateway不能平滑重启,否则会导致连接断开
+     * @var bool
+     */
     public $reloadable = false;
     
+    /**
+     * 心跳时间间隔
+     * @var int
+     */
     public $pingInterval = 0;
 
+    /**
+     * $pingNotResponseLimit*$pingInterval时间内,客户端未发送任何数据,断开客户端连接
+     * @var int
+     */
     public $pingNotResponseLimit = 0;
     
+    /**
+     * 服务端向客户端发送的心跳数据
+     * @var string
+     */
     public $pingData = '';
     
+    /**
+     * 保存客户端的所有connection对象
+     * @var array
+     */
     protected $_clientConnections = array();
     
+    /**
+     * 保存所有worker的内部连接的connection对象
+     * @var array
+     */
     protected $_workerConnections = array();
     
+    /**
+     * gateway内部监听worker内部连接的worker
+     * @var Worker
+     */
     protected $_innerTcpWorker = null;
     
+    /**
+     * gateway内部监听udp数据的worker
+     * @var Worker
+     */
     protected $_innerUdpWorker = null;
     
+    /**
+     * 构造函数
+     * @param string $socket_name
+     * @param array $context_option
+     */
     public function __construct($socket_name, $context_option = array())
     {
         $this->onWorkerStart = array($this, 'onWorkerStart');
@@ -42,15 +95,27 @@ class Gateway extends Worker
         $this->_appInitPath = dirname($backrace[0]['file']);
     }
     
+    /**
+     * 当客户端发来数据时,转发给worker处理
+     * @param TcpConnection $connection
+     * @param mixed $data
+     */
     public function onClientMessage($connection, $data)
     {
         $connection->pingNotResponseCount = 0;
         $this->sendToWorker(GatewayProtocol::CMD_ON_MESSAGE, $connection, $data);
     }
     
+    /**
+     * 当客户端连接上来时,初始化一些客户端的数据
+     * 包括全局唯一的client_id、初始化session等
+     * @param unknown_type $connection
+     */
     public function onClientConnect($connection)
     {
+        // 分配一个全局唯一的client_id
         $connection->globalClientId = $this->createGlobalClientId();
+        // 保存该连接的内部通讯的数据包报头,避免每次重新初始化
         $connection->gatewayHeader = array(
             'local_ip' => $this->lanIp,
             'local_port' => $this->lanPort,
@@ -58,23 +123,35 @@ class Gateway extends Worker
             'client_port'=>$connection->getRemotePort(),
             'client_id'=>$connection->globalClientId,
         );
+        // 连接的session
         $connection->session = '';
+        // 该连接的心跳参数
         $connection->pingNotResponseCount = 0;
+        // 保存客户端连接connection对象
         $this->_clientConnections[$connection->globalClientId] = $connection;
+        // 保存该连接的内部gateway通讯地址
         $address = $this->lanIp.':'.$this->lanPort;
         $this->storeClientAddress($connection->globalClientId, $address);
+        // 如果设置了Event::onConnect,则通知worker进程,让worker执行onConnect
         if(method_exists('Event','onConnect'))
         {
             $this->sendToWorker(GatewayProtocol::CMD_ON_CONNECTION, $connection);
         }
     }
     
+    /**
+     * 发送数据给worker进程
+     * @param int $cmd
+     * @param TcpConnection $connection
+     * @param mixed $body
+     */
     protected function sendToWorker($cmd, $connection, $body = '')
     {
         $gateway_data = $connection->gatewayHeader;
         $gateway_data['cmd'] = $cmd;
         $gateway_data['body'] = $body;
         $gateway_data['ext_data'] = $connection->session;
+        // 随机选择一个worker处理
         $key = array_rand($this->_workerConnections);
         if($key)
         {
@@ -85,6 +162,7 @@ class Gateway extends Worker
                 return false;
             }
         }
+        // 没有可用的worker
         else
         {
             $msg = "endBufferToWorker fail. the connections between Gateway and BusinessWorker are not ready";
@@ -95,8 +173,10 @@ class Gateway extends Worker
     }
     
     /**
+     * 保存客户端连接的gateway通讯地址
      * @param int $global_client_id
      * @param string $address
+     * @return bool
      */
     protected function storeClientAddress($global_client_id, $address)
     {
@@ -113,18 +193,36 @@ class Gateway extends Worker
         return true;
     }
     
+    /**
+     * 删除客户端gateway通讯地址
+     * @param int $global_client_id
+     * @return void
+     */
     protected function delClientAddress($global_client_id)
     {
         Store::instance('gateway')->delete('gateway-'.$global_client_id);
     }
     
+    /**
+     * 当客户端关闭时
+     * @param unknown_type $connection
+     */
     public function onClientClose($connection)
     {
-        $this->sendToWorker(GatewayProtocol::CMD_ON_CLOSE, $connection);
+        // 尝试通知worker,触发Event::onClose
+        if(method_exists('Event','onClose'))
+        {
+            $this->sendToWorker(GatewayProtocol::CMD_ON_CLOSE, $connection);
+        }
+        // 清理连接的数据
         $this->delClientAddress($connection->globalClientId);
         unset($this->_clientConnections[$connection->globalClientId]);
     }
     
+    /**
+     * 创建一个workerman集群全局唯一的client_id
+     * @return int|false
+     */
     protected function createGlobalClientId()
     {
         $global_socket_key = 'GLOBAL_SOCKET_ID_KEY';
@@ -149,32 +247,40 @@ class Gateway extends Worker
         return $global_client_id;
     }
     
+    /**
+     * 当Gateway启动的时候触发的回调函数
+     * @return void
+     */
     public function onWorkerStart()
     {
+        // 分配一个内部通讯端口
         $this->lanPort = $this->startPort - posix_getppid() + posix_getpid();
-    
         if($this->lanPort<0 || $this->lanPort >=65535)
         {
             $this->lanPort = rand($this->startPort, 65535);
         }
         
+        // 如果有设置心跳,则定时执行
         if($this->pingInterval > 0)
         {
             Timer::add($this->pingInterval, array($this, 'ping'));
         }
     
+        // 初始化gateway内部的监听,用于监听worker的连接已经连接上发来的数据
         $this->_innerTcpWorker = new Worker("GatewayProtocol://{$this->lanIp}:{$this->lanPort}");
         $this->_innerTcpWorker->listen();
         $this->_innerUdpWorker = new Worker("GatewayProtocol://{$this->lanIp}:{$this->lanPort}");
         $this->_innerUdpWorker->transport = 'udp';
         $this->_innerUdpWorker->listen();
     
+        // 设置内部监听的相关回调
         $this->_innerTcpWorker->onMessage = array($this, 'onWorkerMessage');
         $this->_innerUdpWorker->onMessage = array($this, 'onWorkerMessage');
         
         $this->_innerTcpWorker->onConnect = array($this, 'onWorkerConnect');
         $this->_innerTcpWorker->onClose = array($this, 'onWorkerClose');
         
+        // 注册gateway的内部通讯地址,worker去连这个地址,以便gateway与worker之间建立起TCP长连接
         if(!$this->registerAddress())
         {
             $this->log('registerAddress fail and exit');
@@ -182,31 +288,45 @@ class Gateway extends Worker
         }
     }
     
+    
+    /**
+     * 当worker通过内部通讯端口连接到gateway时
+     * @param TcpConnection $connection
+     */
     public function onWorkerConnect($connection)
     {
         $connection->remoteAddress = $connection->getRemoteIp().':'.$connection->getRemotePort();
         $this->_workerConnections[$connection->remoteAddress] = $connection;
     }
     
+    /**
+     * 当worker发来数据时
+     * @param TcpConnection $connection
+     * @param mixed $data
+     * @throws \Exception
+     */
     public function onWorkerMessage($connection, $data)
     {
         $cmd = $data['cmd'];
         switch($cmd)
         {
-            // 向某客户端发送数据
+            // 向某客户端发送数据,Gateway::sendToClient($client_id, $message);
             case GatewayProtocol::CMD_SEND_TO_ONE:
                 if(isset($this->_clientConnections[$data['client_id']]))
                 {
                     $this->_clientConnections[$data['client_id']]->send($data['body']);
                 }
                 break;
+                // 关闭客户端连接,Gateway::closeClient($client_id);
             case GatewayProtocol::CMD_KICK:
                 if(isset($this->_clientConnections[$data['client_id']]))
                 {
                     $this->_clientConnections[$data['client_id']]->close();
                 }
                 break;
+                // 广播, Gateway::sendToAll($message, $client_id_array)
             case GatewayProtocol::CMD_SEND_TO_ALL:
+                // $client_id_array不为空时,只广播给$client_id_array指定的客户端
                 if($data['ext_data'])
                 {
                     $client_id_array = unpack('N*', $data['ext_data']);
@@ -218,6 +338,7 @@ class Gateway extends Worker
                         }
                     }
                 }
+                // $client_id_array为空时,广播给所有在线客户端
                 else
                 {
                     foreach($this->_clientConnections as $client_connection)
@@ -226,16 +347,19 @@ class Gateway extends Worker
                     }
                 }
                 break;
+                // 更新客户端session
             case GatewayProtocol::CMD_UPDATE_SESSION:
                 if(isset($this->_clientConnections[$data['client_id']]))
                 {
                     $this->_clientConnections[$data['client_id']]->session = $data['ext_data'];
                 }
                 break;
+                // 获得客户端在线状态 Gateway::getOnlineStatus()
             case GatewayProtocol::CMD_GET_ONLINE_STATUS:
                 $online_status = json_encode(array_keys($this->_clientConnections));
                 $connection->send($online_status);
                 break;
+                // 判断某个client_id是否在线 Gateway::isOnline($client_id)
             case GatewayProtocol::CMD_IS_ONLINE:
                 $connection->send((int)isset($this->_clientConnections[$data['client_id']]));
                 break;
@@ -245,15 +369,20 @@ class Gateway extends Worker
         }
     }
     
+    /**
+     * 当worker连接关闭时
+     * @param TcpConnection $connection
+     */
     public function onWorkerClose($connection)
     {
-        $this->log("{$connection->remoteAddress} CLOSE INNER_CONNECTION\n");
+        //$this->log("{$connection->remoteAddress} CLOSE INNER_CONNECTION\n");
         unset($this->_workerConnections[$connection->remoteAddress]);
     }
     
     /**
-     * 存储全局的通信地址
+     * 存储当前Gateway的内部通信地址
      * @param string $address
+     * @return bool
      */
     protected function registerAddress()
     {
@@ -269,6 +398,7 @@ class Gateway extends Worker
             $this->log($msg);
             return false;
         }
+        // 为保证原子性,需要加锁
         Lock::get();
         $addresses_list = $store->get($key);
         if(empty($addresses_list))
@@ -291,8 +421,9 @@ class Gateway extends Worker
     }
     
     /**
-     * 删除全局的通信地址
+     * 删除当前Gateway的内部通信地址
      * @param string $address
+     * @return bool
      */
     protected function unregisterAddress()
     {
@@ -307,6 +438,7 @@ class Gateway extends Worker
             $this->log($msg);
             return false;
         }
+        // 为保证原子性,需要加锁
         Lock::get();
         $addresses_list = $store->get($key);
         if(empty($addresses_list))
@@ -329,9 +461,13 @@ class Gateway extends Worker
         return true;
     }
     
+    /**
+     * 心跳逻辑
+     * @return void
+     */
     public function ping()
     {
-        // 关闭未回复心跳的连接
+        // 遍历所有客户端连接
         foreach($this->_clientConnections as $connection)
         {
             // 上次发送的心跳还没有回复次数大于限定值就断开
@@ -345,6 +481,10 @@ class Gateway extends Worker
         }
     }
     
+    /**
+     * 当gateway关闭时触发,清理数据
+     * @return void
+     */
     public function onWorkerStop()
     {
         $this->unregisterAddress();

+ 1 - 1
GatewayWorker/Lib/Gateway.php

@@ -20,7 +20,7 @@ class Gateway
     
    /**
     * 向所有客户端(或者client_id_array指定的客户端)广播消息
-    * @param string $message 向客户端发送的消息(可以是二进制数据)
+    * @param string $message 向客户端发送的消息
     * @param array $client_id_array 客户端id数组
     */
    public static function sendToAll($message, $client_id_array = null)

+ 5 - 4
GatewayWorker/Lib/Lock.php

@@ -1,7 +1,8 @@
 <?php
 namespace GatewayWorker\Lib;
 /**
- * lock
+ * 锁
+ * 基于文件锁实现
  */
 class Lock
 {
@@ -12,7 +13,7 @@ class Lock
     private static $fileHandle = null;
     
     /**
-     * get lock
+     * 获取锁
      * @param bool block
      * @return bool
      */
@@ -27,7 +28,7 @@ class Lock
     }
     
     /**
-     * release lock
+     * 释放锁
      * @return true
      */
     public static function release()
@@ -40,7 +41,7 @@ class Lock
     }
     
     /**
-     * get handle
+     * 获得文件句柄
      * @return resource
      */
     protected static function getHandle()

+ 1 - 1
GatewayWorker/Lib/Store.php

@@ -20,7 +20,7 @@ class Store
      */
     public static function instance($config_name)
     {
-        // memcache 驱动
+        // memcached 驱动
         if(\Config\Store::$driver == \Config\Store::DRIVER_MC)
         {
             if(!isset(\Config\Store::$$config_name))

+ 23 - 2
Workerman/Autoloader.php

@@ -1,32 +1,53 @@
 <?php
 namespace Workerman;
 
+// 定义Workerman根目录
 if(!defined('WORKERMAN_ROOT_DIR'))
 {
     define('WORKERMAN_ROOT_DIR', realpath(__DIR__  . '/../'));
 }
-
+// 包含常量定义文件
 require_once WORKERMAN_ROOT_DIR.'/Workerman/Lib/Constants.php';
 
+/**
+ * 自动加载类
+ * @author walkor<walkor@workerman.net>
+ */
 class Autoloader
 {
+    // 应用的初始化目录,作为加载类文件的参考目录
     protected static $_appInitPath = '';
 
+    /**
+     * 设置应用初始化目录
+     * @param string $root_path
+     * @return void
+     */
     public static function setRootPath($root_path)
     {
           self::$_appInitPath = $root_path;
     }
 
+    /**
+     * 根据命名空间加载文件
+     * @param string $name
+     * @return boolean
+     */
     public static function loadByNamespace($name)
     {
+        // 相对路径
         $class_path = str_replace('\\', DIRECTORY_SEPARATOR ,$name);
+        // 先尝试在应用目录寻找文件
         $class_file = self::$_appInitPath . '/' . $class_path.'.php';
+        // 文件不存在,则在workerman根目录中寻找
         if(!is_file($class_file))
         {
             $class_file = WORKERMAN_ROOT_DIR . DIRECTORY_SEPARATOR . "$class_path.php";
         }
+        // 找到文件
         if(is_file($class_file))
         {
+            // 加载
             require_once($class_file);
             if(class_exists($name, false))
             {
@@ -36,5 +57,5 @@ class Autoloader
         return false;
     }
 }
-
+// 设置类自动加载回调函数
 spl_autoload_register('\Workerman\Autoloader::loadByNamespace');

+ 6 - 6
Workerman/Events/EventInterface.php

@@ -4,25 +4,25 @@ namespace Workerman\Events;
 interface EventInterface
 {
     /**
-     * read event
+     * 读事件
      * @var int
      */
     const EV_READ = 1;
     
     /**
-     * write event
+     * 写事件
      * @var int
      */
     const EV_WRITE = 2;
     
     /**
-     * signal
+     * 信号事件
      * @var int
      */
     const EV_SIGNAL = 4;
     
     /**
-     * add 
+     * 添加事件回调 
      * @param resource $fd
      * @param int $flag
      * @param callable $func
@@ -31,7 +31,7 @@ interface EventInterface
     public function add($fd, $flag, $func);
     
     /**
-     * del
+     * 删除事件回调
      * @param resource $fd
      * @param int $flag
      * @return bool
@@ -39,7 +39,7 @@ interface EventInterface
     public function del($fd, $flag);
     
     /**
-     * loop
+     * 事件循环
      * @return void
      */
     public function loop();

+ 5 - 5
Workerman/Events/Libevent.php

@@ -13,19 +13,19 @@ class Libevent implements EventInterface
     protected $eventBase = null;
     
     /**
-     * all events
+     * 所有的事件
      * @var array
      */
     protected $allEvents = array();
     
     /**
-     * all signal events
+     * 所有的信号事件
      * @var array
      */
     protected $eventSignal = array();
     
     /**
-     * create event base
+     * 构造函数
      * @return void
      */
     public function __construct()
@@ -82,7 +82,7 @@ class Libevent implements EventInterface
     }
     
     /**
-     * del
+     * 删除事件
      * @see Events\EventInterface::del()
      */
     public function del($fd ,$flag)
@@ -112,7 +112,7 @@ class Libevent implements EventInterface
     }
 
     /**
-     * loop
+     * 事件循环
      * @see EventInterface::loop()
      */
     public function loop()

+ 16 - 15
Workerman/Events/Select.php

@@ -4,35 +4,36 @@ namespace Workerman\Events;
 class Select implements EventInterface
 {
     /**
-     * all events
+     * 所有的事件
      * @var array
      */
     public $_allEvents = array();
     
     /**
-     * all signal events
+     * 所有信号事件
      * @var array
      */
     public $_signalEvents = array();
     
     /**
-     * read fds
+     * 监听这些描述符的读事件
      * @var array
      */
     protected $_readFds = array();
     
     /**
-     * write fds
+     * 监听这些描述符的写事件
      * @var array
      */
     protected $_writeFds = array();
     
     /**
-     * construct
+     * 构造函数
      * @return void
      */
     public function __construct()
     {
+        // 创建一个管道,放入监听读的描述符集合中,避免空轮询
         $this->channel = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
         if($this->channel)
         {
@@ -42,7 +43,7 @@ class Select implements EventInterface
     }
     
     /**
-     * add
+     * 添加事件及处理函数
      * @see Events\EventInterface::add()
      */
     public function add($fd, $flag, $func)
@@ -69,7 +70,7 @@ class Select implements EventInterface
     }
     
     /**
-     * signal handler
+     * 信号处理函数
      * @param int $signal
      */
     public function signalHandler($signal)
@@ -78,7 +79,7 @@ class Select implements EventInterface
     }
     
     /**
-     * del
+     * 删除某个描述符的某类事件的监听
      * @see Events\EventInterface::del()
      */
     public function del($fd ,$flag)
@@ -108,7 +109,7 @@ class Select implements EventInterface
         return true;
     }
     /**
-     * main loop
+     * 主循环
      * @see Events\EventInterface::loop()
      */
     public function loop()
@@ -116,20 +117,20 @@ class Select implements EventInterface
         $e = null;
         while (1)
         {
-            // calls signal handlers for pending signals
+            // 如果有信号,尝试执行信号处理函数
             pcntl_signal_dispatch();
-            // 
+            
             $read = $this->_readFds;
             $write = $this->_writeFds;
-            // waits for $read and $write to change status
+            // 等待可读或者可写事件
             if(!@stream_select($read, $write, $e, 60))
             {
-                // maybe interrupt by sianals, so calls signal handlers for pending signals
+                // 可能是被信号打断,尝试执行信号处理函数
                 pcntl_signal_dispatch();
                 continue;
             }
             
-            // read
+            // 这些描述符可读,执行对应描述符的读回调函数
             if($read)
             {
                 foreach($read as $fd)
@@ -142,7 +143,7 @@ class Select implements EventInterface
                 }
             }
             
-            // write
+            // 这些描述符可写,执行对应描述符的写回调函数
             if($write)
             {
                 foreach($write as $fd)

+ 5 - 2
Workerman/Lib/Constants.php

@@ -1,10 +1,13 @@
-<?php 
+<?php
+// 如果ini没设置时区,则设置一个默认的
 if(!ini_get('date.timezone') )
 {
     date_default_timezone_set('Asia/Shanghai');
 }
+// 显示错误到终端
 ini_set('display_errors', 'on');
 
+// 连接失败
 define('WORKERMAN_CONNECT_FAIL', 1);
-
+// 发送失败
 define('WORKERMAN_SEND_FAIL', 2);

+ 6 - 6
Workerman/Lib/Timer.php

@@ -5,7 +5,7 @@ use \Exception;
 
 /**
  * 
- * timer
+ * 定时器
  * 
  * <b>example:</b>
  * <pre>
@@ -30,7 +30,7 @@ class Timer
     
     
     /**
-     * init
+     * 初始化
      * @return void
      */
     public static function init($event = null)
@@ -46,7 +46,7 @@ class Timer
     }
     
     /**
-     * signal handler
+     * 信号处理函数,只处理ALARM事件
      * @return void
      */
     public static function signalHandle()
@@ -57,7 +57,7 @@ class Timer
     
     
     /**
-     * add a timer
+     * 添加一个定时器
      * @param int $time_interval
      * @param callback $func
      * @param mix $args
@@ -92,7 +92,7 @@ class Timer
     
     
     /**
-     * tick
+     * 尝试触发定时回调
      * @return void
      */
     public static function tick()
@@ -133,7 +133,7 @@ class Timer
     }
     
     /**
-     * del all
+     * 删除所有定时
      */
     public static function delAll()
     {

+ 15 - 4
Workerman/WebServer.php

@@ -7,7 +7,7 @@ use \Workerman\Protocols\HttpCache;
 
 /**
  * 
- *  WebServer
+ *  基于Worker实现的一个简单的WebServer
  *  HTTP协议
  *  
  * @author walkor <walkor@workerman.net>
@@ -34,7 +34,10 @@ class WebServer extends Worker
     
     
     /**
-     * add server root
+     * 添加站点域名与站点目录的对应关系,类似nginx的
+     * @param string $domain
+     * @param string $root_path
+     * @return void
      */
     public  function addRoot($domain, $root_path)
     {
@@ -42,7 +45,7 @@ class WebServer extends Worker
     }
     
     /**
-     * 
+     * 构造函数
      * @param string $socket_name
      * @param array $context_option
      */
@@ -57,6 +60,7 @@ class WebServer extends Worker
     
     /**
      * 进程启动的时候一些初始化工作
+     * @throws \Exception
      */
     public function onWorkerStart()
     {
@@ -104,7 +108,14 @@ class WebServer extends Worker
     }
     
     /**
-     * 数据接收完整后处理业务逻辑
+     * 当接收到完整的http请求后的处理逻辑
+     * 1、如果请求的是以php为后缀的文件,则尝试加载
+     * 2、如果请求的url没有后缀,则尝试加载对应目录的index.php
+     * 3、如果请求的是非php为后缀的文件,尝试读取原始数据并发送
+     * 4、如果请求的文件不存在,则返回404
+     * @param TcpConnection $connection
+     * @param mixed $data
+     * @return void
      */
     public function onMessage($connection, $data)
     {

+ 3 - 2
Workerman/Worker.php

@@ -1008,7 +1008,7 @@ class Worker
         {
             echo $msg;
         }
-        file_put_contents(self::$logFile, date('Y-m-d H:i:s') . " " . $msg, FILE_APPEND);
+        file_put_contents(self::$logFile, date('Y-m-d H:i:s') . " " . $msg, FILE_APPEND | LOCK_EX);
     }
     
     /**
@@ -1078,11 +1078,12 @@ class Worker
             throw new Exception($errmsg);
         }
         
-        // 尝试打开tcp的keepalive
+        // 尝试打开tcp的keepalive,关闭TCP Nagle算法
         if(function_exists('socket_import_stream'))
         {
             $socket   = socket_import_stream($this->_mainSocket );
             socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);
+            socket_set_option($socket, SOL_SOCKET, TCP_NODELAY, 1);
         }
         
         // 设置非阻塞