Created
October 11, 2012 19:35
-
-
Save andriesss/3874973 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Anse\Xmpp; | |
use Anse\Xmpp\Message\MessageInterface; | |
class Stream | |
{ | |
/** | |
* @var string | |
*/ | |
protected $host; | |
/** | |
* @var int | |
*/ | |
protected $port = 5222; | |
/** | |
* @var int | |
*/ | |
protected $timeout = 30; | |
/** | |
* @var resource | |
*/ | |
private $socket; | |
/** | |
* @param string $host | |
* @param int $port | |
* @param int $timeout | |
*/ | |
public function __construct($host, $port = 5222, $timeout = 30) | |
{ | |
$this->setHost($host); | |
$this->setPort($port); | |
$this->setTimeout($timeout); | |
} | |
public function connect() | |
{ | |
$start = time(); | |
do { | |
$this->socket = stream_socket_client($this->getConnectionString(), $errno, $errstr, $this->timeout); | |
if (false === $this->socket) { | |
throw new \RuntimeException($errstr, $errno); | |
} | |
if (!$this->socket) { | |
sleep($this->timeout); | |
} | |
} while (!$this->socket && (time() - $start) < $this->timeout); | |
if ($this->socket) { | |
stream_set_timeout($this->socket, 1); | |
stream_set_blocking($this->socket, 1); | |
} else { | |
throw new \RuntimeException('Could not connect to server.'); | |
} | |
return $this; | |
} | |
/** | |
* @param Message\MessageInterface $message | |
* @return bool|int | |
*/ | |
public function send(MessageInterface $message) | |
{ | |
$sent = fwrite($this->socket, $message->toXml()); | |
if (false !== $sent) { | |
return $sent; | |
} | |
return false; | |
} | |
/** | |
* Returns if socket has unread bytes | |
* | |
* @return bool | |
*/ | |
public function hasUnreadBytes() | |
{ | |
$meta = stream_get_meta_data($this->socket); | |
return $meta['unread_bytes'] > 0; | |
} | |
/** | |
* @return string | |
*/ | |
public function read() | |
{ | |
$done = false; | |
$response = ''; | |
while (!$done) { | |
$response .= fread($this->socket, 4096); | |
if ($this->hasUnreadBytes() === false) { | |
$done = true; | |
} | |
} | |
return $response; | |
} | |
/** | |
* @param $timeout | |
* @return Stream | |
* @throws \InvalidArgumentException | |
*/ | |
protected function setTimeout($timeout) | |
{ | |
if (!is_integer($timeout)) { | |
throw new \InvalidArgumentException('Invalid timeout provided. Expected integer, got ' . gettype($timeout)); | |
} | |
if ($timeout < 1) { | |
throw new \InvalidArgumentException('Invalid timeout provided. Should be minimum 1 second'); | |
} | |
$this->timeout = $timeout; | |
return $this; | |
} | |
/** | |
* @param $host | |
* @return Stream | |
* @throws \InvalidArgumentException | |
*/ | |
protected function setHost($host) | |
{ | |
if (!is_string($host)) { | |
throw new \InvalidArgumentException('Invalid host provided. Expected string, got ' . gettype($host)); | |
} | |
$this->host = $host; | |
return $this; | |
} | |
/** | |
* @param $port | |
* @return Stream | |
* @throws \InvalidArgumentException | |
*/ | |
protected function setPort($port) | |
{ | |
if (!is_integer($port)) { | |
throw new \InvalidArgumentException('Invalid port provided. Expected integer, got ' . gettype($port)); | |
} | |
$this->port = $port; | |
return $this; | |
} | |
/** | |
* @return string | |
*/ | |
protected function getConnectionString() | |
{ | |
return 'tcp://' . $this->host . ':' . $this->port; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment