Changeset 1815

Show
Ignore:
Timestamp:
09/02/08 00:30:40 (4 months ago)
Author:
mikey
Message:

more work on the protocol handler

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • labs/incubator/src/main/php/net/stubbles/remote/protocol/easc/stubEASCProtocolHandler.php

    r1804 r1815  
    88 * @version     $Id$ 
    99 */ 
    10 stubClassLoader::load('net::stubbles::remote::protocol::stubProtocolHandler', 
     10stubClassLoader::load('net::stubbles::remote::protocol::stubByteCountedString', 
     11                      'net::stubbles::remote::protocol::stubProtocolHandler', 
     12                      'net::stubbles::remote::protocol::easc::stubEASCException', 
    1113                      'net::stubbles::peer::stubBSDSocket' 
    1214); 
     
    3234    protected $version    = array('major' => 0, 'minor' => 0); 
    3335    /** 
     36     * socket used to connect to remote server 
     37     * 
     38     * @var  stubBSDSocket 
     39     */ 
     40    protected $socket; 
     41    /** 
    3442     * magic easc protocol number 
    3543     */ 
    36     const MAGIC_NUMBER  = 0x3c872747; 
     44    const MAGIC_NUMBER    = 0x3c872747; 
    3745    /** 
    3846     * request message type: init 
    3947     */ 
    40     const MSG_INIT      = 0x0000; 
     48    const MSG_INIT        = 0x0000; 
    4149    /** 
    4250     * request message type: lookup 
    4351     */ 
    44     const MSG_LOOKUP    = 0x0001; 
     52    const MSG_LOOKUP      = 0x0001; 
    4553    /** 
    4654     * request message type: call 
    4755     */ 
    48     const MSG_CALL      = 0x0002; 
     56    const MSG_CALL        = 0x0002; 
    4957    /** 
    5058     * request message type: finalize 
    5159     */ 
    52     const MSG_FINALIZE  = 0x0003; 
     60    const MSG_FINALIZE    = 0x0003; 
    5361    /** 
    5462     * request message type: transaction operation 
    5563     */ 
    56     const MSG_TRAN_OP   = 0x0004; 
     64    const MSG_TRAN_OP     = 0x0004; 
    5765    /** 
    5866     * response message type: value 
    5967     */ 
    60     const MSG_VALUE     = 0x0005; 
     68    const MSG_VALUE       = 0x0005; 
    6169    /** 
    6270     * response message type: exception 
    6371     */ 
    64     const MSG_EXCEPTION = 0x0006; 
     72    const MSG_EXCEPTION   = 0x0006; 
    6573    /** 
    6674     * response message type: error 
    6775     */ 
    68     const MSG_ERROR     = 0x0007; 
     76    const MSG_ERROR       = 0x0007; 
    6977    /** 
    7078     * transaction message type: begin of transaction 
    7179     */ 
    72     const TRAN_BEGIN    = 0x0001; 
     80    const TRAN_BEGIN      = 0x0001; 
    7381    /** 
    7482     * transaction message type: state of transaction 
    7583     */ 
    76     const TRAN_STATE    = 0x0002; 
     84    const TRAN_STATE      = 0x0002; 
    7785    /** 
    7886     * transaction message type: commit transaction 
    7987     */ 
    80     const TRAN_COMMIT   = 0x0003; 
     88    const TRAN_COMMIT     = 0x0003; 
    8189    /** 
    8290     * transaction message type: rollback transaction 
    8391     */ 
    84     const TRAN_ROLLBACK = 0x0004; 
     92    const TRAN_ROLLBACK   = 0x0004; 
    8593 
    8694    /** 
     
    9098    { 
    9199        $this->serializer = new stubEASCSerializer(); 
    92         $this->serializer->mapping('I', new stubRemoteInterfaceMapping()); 
    93         $this->serializer->exceptionName('naming/NameNotFound', 'net::stubbles::remote::stubNameNotFoundException'); 
    94         $this->serializer->exceptionName('invoke/Exception', 'net::stubbles::remote::stubInvocationException'); 
    95         $this->serializer->packageMapping('net.xp_framework.easc.reflect', 'net::stubbles::remote::easc::reflect'); 
     100        $this->serializer->addMapping(new stubRemoteInterfaceMapping()); 
     101        $this->serializer->addExceptionMapping('net::stubbles::remote::stubNameNotFoundException', 'naming/NameNotFound'); 
     102        $this->serializer->addExceptionMapping('net::stubbles::remote::stubInvocationException', 'invoke/Exception'); 
     103        $this->serializer->addPackageMapping('net::stubbles::remote::easc::reflect', 'net.xp_framework.easc.reflect'); 
    96104    } 
    97105 
     
    109117               $this->version['minor'] 
    110118        ); 
    111         $this->_sock = new stubBSDSocket($url->getHost('localhost'), $url->getPort(6448)); 
    112         $this->_sock->setOption(getprotobyname('tcp'), TCP_NODELAY, true); 
    113         $this->_sock->connect(); 
     119        $this->socket = new stubBSDSocket($url->getHost('localhost'), $url->getPort(6448)); 
     120        $this->socket->setOption(getprotobyname('tcp'), TCP_NODELAY, true); 
     121        $this->socket->connect(); 
    114122        if ($url->getUser() !== null) { 
    115             $this->sendPacket(self::MSG_INIT, "\1", array(new ByteCountedString($url->getUser()), 
    116                                                           new ByteCountedString($url->getPassword()) 
     123            $this->sendPacket(self::MSG_INIT, "\1", array(new stubByteCountedString($url->getUser()), 
     124                                                          new stubByteCountedString($url->getPassword()) 
    117125                                                    ) 
    118126            ); 
     
    130138    public function lookup($name) 
    131139    { 
    132         return $this->sendPacket(self::MSG_LOOKUP, '', array(new ByteCountedString($name))); 
     140        return $this->sendPacket(self::MSG_LOOKUP, '', array(new stubByteCountedString($name))); 
    133141    } 
    134142 
     
    136144     * begins a transaction 
    137145     * 
    138      * @param   remote.UserTransaction tran 
     146     * @param   UserTransaction tran 
    139147     * @return  bool 
    140148     */ 
    141149    public function begin($tran) 
    142150    { 
    143       return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_BEGIN)); 
     151        return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_BEGIN)); 
    144152    } 
    145153 
     
    147155     * rolls back a transaction 
    148156     * 
    149      * @param   remote.UserTransaction tran 
     157     * @param   UserTransaction tran 
    150158     * @return  bool 
    151159     */ 
    152160    public function rollback($tran) 
    153161    { 
    154       return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_ROLLBACK)); 
     162        return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_ROLLBACK)); 
    155163    } 
    156164 
     
    158166     * commits a transaction 
    159167     * 
    160      * @param   remote.UserTransaction tran 
     168     * @param   UserTransaction tran 
    161169     * @return  bool 
    162170     */ 
    163171    public function commit($tran) 
    164172    { 
    165       return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_COMMIT)); 
     173        return $this->sendPacket(self::MSG_TRAN_OP, pack('N', self::TRAN_COMMIT)); 
    166174    } 
    167175 
     
    170178     * and given arguments 
    171179     * 
    172      * @param   int               $oid     id of the object to invoke the method on 
    173      * @param   string            $method  the name of the method to invoke 
    174      * @param   array<int,mixed>  $args    arguments for the method to invoke 
     180     * @param   int     $oid     id of the object to invoke the method on 
     181     * @param   string  $method  the name of the method to invoke 
     182     * @param   mixed   $args    arguments for the method to invoke 
    175183     * @return  mixed 
    176      * @throws  stubRemoteException 
    177      */ 
    178     public function invoke($oid, $method, array $args) 
    179     { 
    180         return $this->sendPacket(self::MSG_CALL, pack('NN', 0, $oid), array(new ByteCountedString($method), 
    181                                                                             new ByteCountedString($this->serializer->representationOf($args)) 
    182                                                                       ) 
     184     */ 
     185    public function invoke($oid, $method, $args) 
     186    { 
     187        return $this->sendPacket(self::MSG_CALL, 
     188                                 pack('NN', 0, $oid), 
     189                                 array(new stubByteCountedString($method), 
     190                                       new stubByteCountedString($this->serializer->serialize(stubArrayList::with(array($args)))) 
     191                                 ) 
    183192               ); 
    184193    } 
     
    187196     * sends a packet, reads and evaluates the response 
    188197     * 
    189      * @param   int                       $type 
    190      * @param   string                    $data   optional 
    191      * @param   array<ByteCountedString>  $bytes  optional 
     198     * @param   int                           $type 
     199     * @param   string                        $data   optional 
     200     * @param   array<stubByteCountedString>  $bytes  optional 
    192201     * @return  mixed 
    193      * @throws  remote.RemoteException for server errors 
    194      * @throws  lang.Error for unrecoverable errors 
     202     * @throws  stubRemoteException for server errors 
     203     * @throws  stubEASCException    for unrecoverable errors 
    195204     */ 
    196205    protected function sendPacket($type, $data = '', array $bytes = array()) 
    197206    { 
    198207        $bsize = sizeof($bytes); 
    199         // Calculate packet length 
     208        // calculate packet length 
    200209        $length = strlen($data); 
    201210        for ($i = 0; $i < $bsize; $i++) { 
     
    205214        // Write packet 
    206215        $packet = pack('Nc4Na*',  
    207                        self::MAGIC_NUMBER,  
    208                        $this->versionMajor, 
    209                        $this->versionMinor, 
    210                        $type, 
    211                        false, 
    212                        $length, 
    213                        $data 
     216                       self::MAGIC_NUMBER,      // magic number to ensure correctness of message 
     217                       $this->versionMajor,     // version: major 
     218                       $this->versionMinor,     // version: minor 
     219                       $type,                   // message type 
     220                       false,                   // compression: always false, probably used in later protocol versions 
     221                       $length,                 // length of data to follow 
     222                       $data                    // the real data to send 
    214223        ); 
    215224 
    216225        try { 
    217             $this->_sock->write($packet); 
     226            $this->socket->write($packet); 
    218227            for ($i = 0; $i < $bsize; $i++) { 
    219                 $bytes[$i]->writeTo($this->_sock); 
     228                $bytes[$i]->writeTo($this->socket); 
    220229            } 
    221230 
    222231            $header = unpack('Nmagic/cvmajor/cvminor/ctype/ctran/Nlength', $this->readBytes(12)); 
    223         } catch (IOException $e) { 
    224             throw new RemoteException($e->getMessage(), $e); 
     232        } catch (stubConnectionException $ce) { 
     233            throw new stubRemoteException($ce->getMessage(), $ce); 
    225234        } 
    226235 
    227236        if (self::MAGIC_NUMBER != $header['magic']) { 
    228             $this->_sock->close(); 
    229             throw new Error('Magic number mismatch (have: ' . $header['magic'] . ' expect: ' . self::MAGIC_NUMBER); 
     237            $this->socket->close(); 
     238            throw new stubEASCException('Magic number mismatch (have: ' . $header['magic'] . ' expect: ' . self::MAGIC_NUMBER); 
    230239        } 
    231240 
    232241        // Perform actions based on response type 
    233         $ctx = array('handler' => $this); 
     242        $context = array('handler' => $this); 
    234243        try { 
    235244            switch ($header['type']) { 
    236245                case self::MSG_VALUE: 
    237                     $data = ByteCountedString::readFrom($this->_sock); 
    238                     return $this->serializer->unserialize(new stubPHPSerializedData($data), $ctx); 
     246                    $data = stubByteCountedString::readFrom($this->socket); 
     247                    return $this->serializer->unserialize(new stubPHPSerializedData($data), $context); 
    239248 
    240249                case self::MSG_EXCEPTION: 
    241                     $data      = ByteCountedString::readFrom($this->_sock); 
    242                     $reference = $this->serializer->unserialize(new stubPHPSerializedData($data), $ctx); 
    243                     if ($reference instanceof RemoteException) { 
     250                    $data      = stubByteCountedString::readFrom($this->socket); 
     251                    $reference = $this->serializer->unserialize(new stubPHPSerializedData($data), $context); 
     252                    if ($reference instanceof stubRemoteException) { 
    244253                        throw $reference; 
    245                     } elseif ($reference instanceof ExceptionReference) { 
    246                         throw new RemoteException($reference->getMessage(), $reference); 
    247                     } else { 
    248                         throw new RemoteException('lang.XPException', new XPException($this->stringOf($reference))); 
     254                    } elseif ($reference instanceof stubExceptionReference) { 
     255                        throw new stubRemoteException($reference->getMessage(), $reference); 
    249256                    } 
     257                     
     258                    throw new stubRemoteException('lang.XPException', new XPException($this->stringOf($reference))); 
    250259 
    251260                case self::MSG_ERROR: 
    252                     $message = ByteCountedString::readFrom($this->_sock);    // Not serialized! 
    253                     $this->_sock->close(); 
    254                     throw new RemoteException($message, new Error($message)); 
     261                    $message = stubByteCountedString::readFrom($this->socket);    // not serialized! 
     262                    $this->socket->close(); 
     263                    throw new stubRemoteException($message, new stubEASCException($message)); 
    255264 
    256265                default: 
    257                     $data = $this->readBytes($header['length']);   // Read all left-over bytes 
    258                     $this->_sock->close(); 
    259                     throw new Error('Unknown message type'); 
     266                    $data = $this->readBytes($header['length']); 
     267                    $this->socket->close(); 
     268                    throw new stubEASCException('Unknown message type: ' . $data); 
    260269            } 
    261         } catch (IOException $e) { 
    262             throw new RemoteException($e->getMessage(), $e); 
     270        } catch (stubConnectionException $ce) { 
     271            throw new stubRemoteException($ce->getMessage(), $ce); 
    263272        } 
    264273    } 
     
    270279     * @return  string  
    271280     */ 
    272     protected function readBytes($num
     281    protected function readBytes($amount
    273282    { 
    274283        $return = ''; 
    275         while (strlen($return) < $num) { 
    276             $buf = $this->_sock->readBinary($num - strlen($return)); 
    277             if (0 === strlen($buf)) { 
     284        while (strlen($return) < $amount) { 
     285            $buffer = $this->socket->readBinary($amount - strlen($return)); 
     286            if (0 === strlen($buffer)) { 
    278287                return null; 
    279288            } 
    280289             
    281             $return .= $buf
     290            $return .= $buffer
    282291        } 
    283292