Эх сурвалжийг харах

Fix tcp connection lost bug and EV_WRITE register twice bug.

1.Fix AsyncTcpConnection being unset in TcpConnection::$connections and
never add back when reconnected.
2.Fix AsyncTcpConnection adding EV_WRITE event multi times in ssl
handshake stage.
Ares 7 жил өмнө
parent
commit
aff12aebeb

+ 17 - 16
Connection/AsyncTcpConnection.php

@@ -158,13 +158,12 @@ class AsyncTcpConnection extends TcpConnection
         self::$statistics['connection_count']++;
         $this->maxSendBufferSize        = self::$defaultMaxSendBufferSize;
         $this->_contextOption           = $context_option;
-        static::$connections[$this->id] = $this;
     }
 
     /**
      * Do connect.
      *
-     * @return void 
+     * @return void
      */
     public function connect()
     {
@@ -199,7 +198,7 @@ class AsyncTcpConnection extends TcpConnection
             }
             return;
         }
-        // Add socket to global event loop waiting connection is successfully established or faild. 
+        // Add socket to global event loop waiting connection is successfully established or faild.
         Worker::$globalEvent->add($this->_socket, EventInterface::EV_WRITE, array($this, 'checkConnection'));
         // For windows.
         if(DIRECTORY_SEPARATOR === '\\') {
@@ -228,7 +227,7 @@ class AsyncTcpConnection extends TcpConnection
     /**
      * Get remote address.
      *
-     * @return string 
+     * @return string
      */
     public function getRemoteHost()
     {
@@ -276,14 +275,8 @@ class AsyncTcpConnection extends TcpConnection
      */
     public function checkConnection($socket)
     {
-        // Remove EV_EXPECT for windows.
-        if(DIRECTORY_SEPARATOR === '\\') {
-            Worker::$globalEvent->del($socket, EventInterface::EV_EXCEPT);
-        }
         // Check socket state.
         if ($address = stream_socket_get_name($socket, true)) {
-            // Remove write listener.
-            Worker::$globalEvent->del($socket, EventInterface::EV_WRITE);
             // Nonblocking.
             stream_set_blocking($socket, 0);
             // Compatible with hhvm
@@ -298,14 +291,24 @@ class AsyncTcpConnection extends TcpConnection
             }
 
             // SSL handshake.
-            if ($this->transport === 'ssl' && $this->doSslHandshake($socket)) {
-                $this->_sslHandshakeCompleted = true;
+            if ($this->transport === 'ssl') {
+                $this->_sslHandshakeCompleted = $this->doSslHandshake($socket);
+                if(!$this->_sslHandshakeCompleted){
+                    return;
+                }
+            }
+            
+            // Remove EV_EXPECT for windows.
+            if(DIRECTORY_SEPARATOR === '\\') {
+                Worker::$globalEvent->del($socket, EventInterface::EV_EXCEPT);
             }
+            // Remove write listener.
+            Worker::$globalEvent->del($socket, EventInterface::EV_WRITE);
 
             // Register a listener waiting read event.
             Worker::$globalEvent->add($socket, EventInterface::EV_READ, array($this, 'baseRead'));
             // There are some data waiting to send.
-            if ($this->_sendBuffer && $this->transport !== 'ssl') {
+            if ($this->_sendBuffer) {
                 Worker::$globalEvent->add($socket, EventInterface::EV_WRITE, array($this, 'baseWrite'));
             }
             $this->_status                = self::STATUS_ESTABLISHED;
@@ -335,6 +338,7 @@ class AsyncTcpConnection extends TcpConnection
                     exit(250);
                 }
             }
+            static::$connections[$this->id] = $this;
         } else {
             // Connection failed.
             $this->emitError(WORKERMAN_CONNECT_FAIL, 'connect ' . $this->_remoteAddress . ' fail after ' . round(microtime(true) - $this->_connectStartTime, 4) . ' seconds');
@@ -382,9 +386,6 @@ class AsyncTcpConnection extends TcpConnection
                 exit(250);
             }
         }
-        if ($this->_sendBuffer) {
-            Worker::$globalEvent->add($socket, EventInterface::EV_WRITE, array($this, 'baseWrite'));
-        }
         return true;
     }
 }