1
0
Fork 0
mirror of https://github.com/Yetangitu/ampache synced 2025-10-03 09:49:30 +02:00
ampache/modules/xbmc-php-rpc/TCPClient.php
2013-11-05 20:40:13 -05:00

139 lines
No EOL
4 KiB
PHP

<?php
require_once 'Client.php';
class XBMC_RPC_TCPClient extends XBMC_RPC_Client {
/**
* @var resource A file pointer resource for reading over the connected socket.
* @access private
*/
private $fp;
/**
* Destructor.
*
* Cleans up the file resource if necessary.
*/
public function __destruct() {
if (is_resource($this->fp)) {
fclose($this->fp);
}
}
/**
* Asserts that the server is reachable and a connection can be made.
*
* @return void
* @exception XBMC_RPC_ConnectionException if it is not possible to connect to
* the server.
* @access protected
*/
protected function assertCanConnect() {
if (!$this->canConnect()) {
throw new XBMC_RPC_ConnectionException('Unable to connect to XBMC server via TCP');
}
}
/**
* Prepares for a connection to XBMC via TCP.
*
* @return void
* @access protected
*/
protected function prepareConnection() {
$parameters = $this->server->getParameters();
$this->fp = @fsockopen($parameters['host'], $parameters['port']);
}
/**
* Sends a JSON-RPC request to XBMC and returns the result.
*
* @param string $json A JSON-encoded string representing the remote procedure call.
* This string should conform to the JSON-RPC 2.0 specification.
* @param string $rpcId The unique ID of the remote procedure call.
* @return string The JSON-encoded response string from the server.
* @exception XBMC_RPC_RequestException if it was not possible to make the request.
* @access protected
* @link http://groups.google.com/group/json-rpc/web/json-rpc-2-0 JSON-RPC 2.0 specification
*/
protected function sendRequest($json, $rpcId) {
$this->prepareConnection();
if (!$this->canConnect()) {
throw new XBMC_RPC_ConnectionException('Lost connection to XBMC server');
}
fwrite($this->fp, $json);
while (true) {
$result = $this->readJsonObject();
if (strpos($result, '"id" : "' . $rpcId . '"') !== false) {
break;
}
if (strpos($result, '"id":"' . $rpcId . '"') !== false) {
break;
}
}
fclose($this->fp);
return $result;
}
/**
* Checks if it is possible to connect to the server.
*
* @return bool True if it is possible to connect, false if not.
* @access private
*/
private function canConnect() {
return is_resource($this->fp);
}
/**
* Reads a single JSON object from the socket and returns it.
*
* @return string The JSON object string from the server.
* @access private
*/
private function readJsonObject() {
$open = $close = 0;
$escaping = false;
$quoteChar = null;
$result = '';
while (false !== ($char = fgetc($this->fp))) {
if (!$escaping) {
switch ($char) {
case "'":
case '"':
if (null === $quoteChar) {
$quoteChar = $char;
} elseif ($quoteChar == $char) {
$quoteChar = null;
}
break;
case '{':
if (null === $quoteChar) {
++$open;
}
break;
case '}':
if (null === $quoteChar) {
++$close;
}
break;
case '\\':
$escaping = true;
break;
}
} else {
$escaping = false;
}
$result .= $char;
if ($open == $close) {
break;
}
}
return $result;
}
}