2016-04-13 8 views
8

twitter stream API'u aramak için owlycode/streaming-bird bir besteci paketi kullanıyorum. Akış API'si, belirtilen bir anahtar kelimeye sahip tweet'leri almak için uygulamanızla Twitter arasında bir yuva açar. Benim durumumda anahtar kelime 'merhaba'.PHP'de, hala bir soket takılıysa, soket tutucum yoksa nasıl kontrol edilir?

İşte kod kullanarak owlycode/akış-kuş paketidir:

<?PHP 
    $oauthToken = ''; 
    $oauthSecret = ''; 
    $consumerKey = ''; 
    $consumerSecret = ''; 

    $bird = new StreamingBird($consumerKey, $consumerSecret, $oauthToken, $oauthSecret); 

    $bird 
     ->createStreamReader(StreamReader::METHOD_FILTER) 
     ->setTrack(['hello']) // Fetch every tweet containing one of the following words 
     ->consume(function ($tweet) { // Now we provide a callback to execute on every received tweet. 
      echo '------------------------' . "\n"; 
      echo $tweet['text'] . "\n"; 
     }); 
    ?> 

Benim sorunum bu bağlantı hatası kapatıldığında, bunu biliyorum alamıyorum olduğunu. Bu yüzden tekrar twitter ile yeniden bağlanamıyorum.

PHP'de, etki alanı adlarına göre açık yuvaları araştıran bir şey var mı?

Belki

check_if_socket_open('https://stream.twitter.com/1.1/statuses/firehose.json') 

gibi bir şey?

Not: Soket değişkeni olmadığı için socket_get_status kullanamıyorum.

+0

O [bana bakar] (https://github.com/OwlyCode/StreamingBird/blob/master/src/StreamReader.php#L80) bağlantı kesilirse soketin yeniden bağlanmasını sağlar. – miken32

+0

Sadece satır içi belgelere bakarak, miken32'nin doğru gibi göründüğü gibi, sorunun bağlantı kaybını algılamak için gereken süredir olduğunu düşünüyorum ... örneğin: zaman aşımı varsayılanı 1 dakikadır ... – edhurtig

+0

akışının 1 dakikasını kaybetti Kötü bir çözüm olsa da, başka nedenlerden dolayı stream_set_timeout ($ stream, $ saniyeler) içine bakmaya değer olabilir. http://php.net/manual/en/function.stream-set-timeout.php – edhurtig

cevap

1

Paketin kendisinde küçük bir ekleme yaparsanız socket_get_status'u kullanabilirsiniz.

Bu iki işlev akış yürütücü sınıfındadır, soket işleyicisi burada bulunur. yuva veri okumak çalışırken soket durumunu kapmak böylece

public function consume(callable $handler) 
{ 
    $this->running = true; 
    while ($this->running) { /// while $this->running is true socket will try to reconnect always. 
     $this->consumeOnce($handler); 
    } 
} 
    protected function consumeOnce(callable $handler) 
    { 
     $this->connection = $this->connect(); 
     $lastStreamActivity = time(); 
     $this->connection->read(function ($tweet) use (&$lastStreamActivity, $handler) { 
      $idle = (time() - $lastStreamActivity); 
      $this->monitor->stat('max_idle_time', $idle); 
      $this->monitor->stat('idle_time', $idle); 
      $this->monitor->stat('tweets', 1); 
      $lastStreamActivity = time(); 
      call_user_func($handler, $tweet, $this->monitor); 
     }); 
     $this->connection->close(); 
    } 

bağlantı sınıfta birden soket işleyici mevcuttur. Aşağıda prize hiç bıraktık eğer soket durumunu kontrol etmek yolu yoktur biraz değiştirilmiş okuma fonksiyonu

public function read(callable $callback, $timeout = 5) 
     { 
      $this->pool = [$this->connection]; 
    stream_set_timeout($this->connection, $timeout); 
    $info = stream_get_meta_data($this->connection); 
      while ($this->connection !== null && !feof($this->connection) && stream_select($this->pool, $fdw, $fde, $timeout) !== false && $info['timed_out']!==true) { 
       // @todo safeguard no tweets but connection OK. (reconnect) 
       $this->pool = [$this->connection]; 
       $chunkInfo = trim(fgets($this->connection)); 
       if (!$chunkInfo) { 
        continue; 
       } 
       $len = hexdec($chunkInfo) + 2; 
       $streamInput = ''; 
       while (!feof($this->connection)) { 
        $streamInput .= fread($this->connection, $len-strlen($streamInput)); 
        if (strlen($streamInput)>=$len) { 
         break; 
        } 
       } 
       $this->buffer .= substr($streamInput, 0, -2); 
       $data = json_decode($this->buffer, true); 
       if ($data) { 
        call_user_func($callback, $data); 
        $this->buffer = ''; 
       } 
      } 
     } 
4

olduğunu. ,

<?php 
class MyStreamReader extends \OwlyCode\StreamingBird 
{ 
    protected $stream; 

    protected function connect($timeout = 5, $attempts = 10) 
    { 
    return $this->stream = parent::connect($timeout, $attempts); 
    } 

    protected function isConnected() 
    { 
    return $this->stream && stream_get_meta_data($this->stream)['eof']; 
    } 
} 


class MyStreamingBird extends \OwlyCode\StreamingBird 
{ 
    public function createStreamReader($method) 
    { 
    $oauth = new \OwlyCode\StreamingBird\Oauth($this->consumerKey, 
     $this->consumerSecret, $this->oauthToken, $this->oauthSecret); 
    return new MyStreamReader(new \OwlyCode\StreamingBird\Connection(), $oauth, $method); 
    } 
} 


$bird = new MyStreamingBird($consumerKey, $consumerSecret, $oauthToken, $oauthSecret); 
$reader = $bird->createStreamReader(StreamReader::METHOD_FILTER); // ... 

$reader->isConnected(); 

Ayrıca \OwlyCode\StreamingBird dayalı bir sınıf yapabiliriz: Buna StreamBird kodunu dokunmadan geçici bir çözüm için arama yapıyorsanız

, o zaman o zaman onun connect yöntemini uygulamak, \OwlyCode\StreamingBird dayalı bir sınıf yapabilirsiniz Akarsuya da erişimi vardır. Ancak, bu akışları takip etmeniz gerekir, çünkü bu bir fabrika yöntemidir. implementation of class StreamingBird baktığımızda

1

, bağlantı üzerinden tam kontrol ile, kolayca streamreader örneğini kendiniz oluşturabilirsiniz bkz:

namespace \OwlyCode\StreamingBird; 
// Let's instantiate the Oauth signature handler 
$oauth = new Oauth($consumerKey, $consumerSecret, $oauthToken, $oauthSecret); 
// Let's create our own Connection object! 
$connection = new Connection(); 

// And here comes our Reader 
$reader = new StreamReader($connection, $oauth, StreamReader::METHOD_FILTER); 
$reader->setTrack(['hello']) 
     ->consume(function ($tweet) { 
      echo '------------------------' . "\n"; 
      echo $tweet['text'] . "\n"; 
     }); 

// Voilà 
print_r(socket_get_status($connection->connection)); 

Connection object stores the socket resource in a public property $connection:

public $connection; 
// ... 
@$this->connection = fsockopen($host, $port, $errNo, $errStr, $timeout);