Exemplo n.º 1
0
 public function onAcceptEvent($bindSocket, $events, $arg)
 {
     $bindSocketId = $arg[0];
     Debug::netEvent(get_class($this) . '::' . __METHOD__ . '(' . $bindSocketId . ') invoked.');
     // add to accept next event
     // why not use EV_PERSIST
     event_add($this->bindSocketEvPool[$bindSocketId]);
     $connSocket = stream_socket_accept($this->bindSocketPool[$bindSocketId]);
     if (!$connSocket) {
         Debug::netErrorEvent(get_class($this) . ': can not accept new TCP-socket');
         return;
     }
     stream_set_blocking($connSocket, 0);
     list($ip, $port) = explode(':', stream_socket_get_name($connSocket, true));
     $connId = daemon::getNextConnId();
     $evBuf = event_buffer_new($connSocket, array($this, 'onEvBufReadEvent'), array($this, 'onEvBufWriteEvent'), array($this, 'onEventEvent'), array($connId));
     event_buffer_base_set($evBuf, daemon::$eventBase);
     event_buffer_priority_set($evBuf, 10);
     event_buffer_watermark_set($evBuf, EV_READ, $this->evBufLowMark, $this->evBufHighMark);
     if (!event_buffer_enable($evBuf, EV_READ | EV_WRITE | EV_PERSIST)) {
         Debug::netErrorEvent(get_class($this) . '::' . __METHOD__ . ': can not set base of buffer. #' . $connId);
         //close socket
         stream_socket_shutdown($connSocket, STREAM_SHUT_RDWR);
         fclose($connSocket);
         return;
     }
     // 调试这里时,浪费了很多时间,必须注意的是,以上 event 所用的变量如果在函数中,如果没有交给其他的变量引用,在函数结束时就会销毁,
     // 造成连接直接断或者bufferevent 不能触发。晕啊晕。
     $this->connSocketPool[$connId] = $connSocket;
     $this->connEvBufPool[$connId] = $evBuf;
     $this->updateLastContact($connId);
     $this->onAccepted($connId, $ip, $port);
 }
Exemplo n.º 2
0
 public function connectTo($host, $port, $blockConnect = false)
 {
     Debug::netEvent(get_class($this) . '::' . __METHOD__ . '(' . $host . ':' . $port . ') invoked.');
     $connSocket = stream_socket_client("tcp://{$host}:{$port}", $errno, $errstr, 30);
     //add err connect
     stream_set_blocking($connSocket, 0);
     if (!is_resource($connSocket)) {
         Debug::netErrorEvent(get_class($this) . ': can not add errorneus socket with address \'' . $host . ':' . $port . '\'.');
         return false;
     }
     $connId = daemon::getNextSocketId();
     //@todo 增加阻塞 connect , 这样可以返回 connId 的时候 socketSession 已经建立好
     if ($blockConnect) {
     }
     $ev = event_new();
     // why not use EV_PERSIST, is because first event is acceptEvent?
     if (!event_set($ev, $connSocket, EV_WRITE, array($this, 'onConnectedEvent'), array($connId))) {
         Debug::netErrorEvent(get_class($this) . '::' . __METHOD__ . ': can not set onAcceptEvent() on binded socket: ' . Debug::dump($connSocket));
         return false;
     }
     event_base_set($ev, daemon::$eventBase);
     event_add($ev, 1 * 1000 * 1000);
     $this->checkConnSocketPool[$connId] = $connSocket;
     $this->checkConnEvPool[$connId] = $ev;
     return $connId;
 }
Exemplo n.º 3
0
 /**
  * Data decoding, according to related IETF draft
  *
  * @see http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#page-16
  */
 protected function _dataDecode()
 {
     //参考 http://blog.csdn.net/fenglibing/article/details/6852497
     //这里仅仅处理最基本的
     $encodedData =& $this->webSocketSession->buf;
     // 至少有2个字节的头
     while (($buflen = strlen($encodedData)) >= 2) {
         $len = 0;
         $isMasked = (bool) (ord($encodedData[1]) >> 7);
         $opcode = ord($encodedData[0]) & 15;
         $dataLength = ord($encodedData[1]) & 127;
         $len += 2;
         if ($dataLength === 126) {
             $extDataLength = hexdec(sprintf('%02x%02x', ord($encodedData[2]), ord($encodedData[3])));
             $len += 2;
         } else {
             if ($dataLength === 127) {
                 $extDataLength = hexdec(sprintf('%02x%02x%02x%02x%02x%02x%02x%02x', ord($encodedData[2]), ord($encodedData[3]), ord($encodedData[4]), ord($encodedData[5]), ord($encodedData[6]), ord($encodedData[7]), ord($encodedData[8]), ord($encodedData[9])));
                 $len += 8;
             } else {
                 $extDataLength = $dataLength;
             }
         }
         if (webSocketSession::maxPacketSize <= $extDataLength) {
             // Too big packet
             $this->webSocketSession->close();
             return;
         }
         if ($isMasked) {
             $maskingKey = Utils::binarySubstr($encodedData, $len, 4);
             $len += 4;
         }
         if ($extDataLength + $len > strlen($encodedData)) {
             //没有出现包
             // not enough data yet
             return;
         }
         $data = Utils::binarySubstr($encodedData, $len, $extDataLength);
         //这里用的引用,所以会处理掉 socketSession->buf
         $encodedData = Utils::binarySubstr($encodedData, $len + $extDataLength);
         if ($opcode === self::CLOSE) {
             //客户端主动关闭连接
             $this->webSocketSession->close();
             return;
         }
         if ($opcode === self::PING) {
             $this->sendFrame('', 'PONG');
             continue;
         }
         if ($opcode === self::PONG) {
             //todo: 收到 pong 包,不做任何事情,以后应该更新最后的连接时间
             daemon::log(get_class($this) . '::' . __METHOD__ . ' : receive PONG packet. ' . $this->webSocketSession->addr);
             continue;
         }
         if ($isMasked) {
             $unmaskingFunc = function ($data, $mask) {
                 for ($i = 0, $l = strlen($data); $i < $l; $i++) {
                     // Avoid storing a new copy of $data...
                     $data[$i] = $data[$i] ^ $mask[$i % 4];
                 }
                 return $data;
             };
             $this->webSocketSession->onFrame($unmaskingFunc($data, $maskingKey), $opcode);
         } else {
             $this->webSocketSession->onFrame($data, $opcode);
         }
     }
 }
Exemplo n.º 4
0
<?php

require_once 'stdin.php';
require_once 'noSQLite.php';
$stdin = new stdin();
$stdin->service = 'noSQLi';
$daemon = new daemon($stdin);
$daemon->setService($stdin->service);
$daemon->run();
class listener
{
    public $socket;
    public $method;
    public $arguments = array();
    public $meta = array();
    public $header;
    const HEADER_LENGTH = 2;
    const ARGUMENT_HEADER_LENGTH = 4;
    const RESPONSE_LENGTH = 4;
    const SIGNAL_ACK = 'ACK';
    const SIGNAL_ERR = 'ERROR';
    public function __construct($socket)
    {
        $this->socket = $socket;
    }
    public function metaUnpackString($arguments)
    {
        $unpackString = 'Lmethod/';
        for ($i = 0, $c = $arguments; $i < $c; $i++) {
            $unpackString .= 'Largument' . ($i + 1) . '/';
        }