2016-04-13 19 views
8

Tôi đang sử dụng gói nhà soạn nhạc owlycode/streaming-bird để gọi twitter stream API. API luồng mở ra một ổ cắm giữa ứng dụng và twitter của bạn, để nhận các tweet có từ khóa được chỉ định. Trong trường hợp của tôi, từ khóa là 'hello'.Làm thế nào để kiểm tra trong PHP, nếu một ổ cắm vẫn kết nối, nếu tôi không có bộ xử lý socket?

Đây là đoạn mã sử dụng gói owlycode/trực tuyến-chim:

<?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"; 
     }); 
    ?> 

Vấn đề của tôi là khi kết nối này đã bị đóng bởi lỗi, tôi không thể biết điều đó. Vì vậy, tôi không thể kết nối lại với twitter nữa.

Có bất kỳ điều gì trong PHP tìm kiếm các ổ cắm mở dựa trên tên miền của chúng không?

Có lẽ cái gì đó như

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

?

Lưu ý: Tôi không thể sử dụng socket_get_status, vì tôi không có biến socket.

+0

Nó [vẻ với tôi] (https://github.com/OwlyCode/StreamingBird/blob/master/src/StreamReader.php#L80) như nó sẽ tiếp tục kết nối lại ổ cắm nếu kết nối bị mất. – miken32

+0

Chỉ cần nhìn vào tài liệu nội tuyến, có vẻ như @ miken32 là chính xác, tôi nghĩ vấn đề là thời gian cần thiết để phát hiện mất kết nối ... ví dụ: nếu thời gian chờ mặc định là 1 phút ... thì bạn sẽ có mất 1 phút của luồng – edhurtig

+0

Mặc dù đây là giải pháp tồi ... nhưng có thể đáng xem xét luồng stream_set_timeout ($ stream, $ giây) vì các lý do khác. http://php.net/manual/en/function.stream-set-timeout.php – edhurtig

Trả lời

1

Dường như bạn có thể sử dụng socket_get_status sau khi tất cả nếu bạn chỉ cần thực hiện một bổ sung nhỏ trong gói chính nó.

Hai chức năng này nằm trong lớp trình phân luồng, trình xử lý socket có sẵn tại đây.

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(); 
    } 

Trong lớp kết nối bạn có xử lý ổ cắm có sẵn để bạn có thể lấy tình trạng ổ cắm khi cố gắng đọc dữ liệu từ ổ cắm. Dưới đây là một chức năng đọc chút thay đổi

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

Không có cách nào để kiểm tra tình trạng ổ cắm, nếu bạn không có quyền truy cập vào các ổ cắm.

Nếu bạn đang tìm kiếm một cách giải quyết mà không cần chạm đang StreamBird, sau đó bạn có thể làm cho một lớp học dựa trên \OwlyCode\StreamingBird, sau đó thực hiện phương pháp connect của nó:

<?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(); 

Bạn cũng có thể làm cho một lớp học dựa trên \OwlyCode\StreamingBird, cũng có quyền truy cập vào luồng. Tuy nhiên, bạn sẽ phải theo dõi các luồng này, bởi vì nó là một phương pháp nhà máy.

1

Nhìn vào implementation of class StreamingBird, bạn sẽ thấy bạn có thể dễ dàng tạo ra các ví dụ StreamReader chính mình, với toàn quyền kiểm soát các kết nối:

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)); 

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

public $connection; 
// ... 
@$this->connection = fsockopen($host, $port, $errNo, $errStr, $timeout); 
Các vấn đề liên quan