SocketInterface
Added unix socket methods to interface, replaced __call/call_user_func calls with concrete methods
This commit is contained in:
parent
02ffd6f782
commit
1b01582ab9
@ -64,11 +64,9 @@ class App implements ApplicationInterface {
|
|||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
ob_implicit_flush();
|
ob_implicit_flush();
|
||||||
|
|
||||||
$host->set_nonblock();
|
|
||||||
declare(ticks = 1);
|
declare(ticks = 1);
|
||||||
|
|
||||||
$host->bind($address, (int)$port);
|
$host->set_nonblock()->bind($address, (int)$port)->listen();
|
||||||
$host->listen();
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$this->loop($host);
|
$this->loop($host);
|
||||||
|
@ -38,6 +38,6 @@ class SendMessage extends ActionTemplate {
|
|||||||
throw new \UnexpectedValueException("Message is empty");
|
throw new \UnexpectedValueException("Message is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->getConnection()->getSocket()->write($this->_message, strlen($this->_message));
|
$this->getConnection()->getSocket()->deliver($this->_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ use Ratchet\Application\ProtocolInterface;
|
|||||||
/**
|
/**
|
||||||
* A wrapper for the PHP socket_ functions
|
* A wrapper for the PHP socket_ functions
|
||||||
* @author Chris Boden <shout at chrisboden dot ca>
|
* @author Chris Boden <shout at chrisboden dot ca>
|
||||||
|
* @link http://ca2.php.net/manual/en/book.sockets.php
|
||||||
* @todo Possibly move this into Ratchet\Resource - another concrete could use streams
|
* @todo Possibly move this into Ratchet\Resource - another concrete could use streams
|
||||||
*/
|
*/
|
||||||
class Socket implements SocketInterface {
|
class Socket implements SocketInterface {
|
||||||
@ -51,10 +52,6 @@ class Socket implements SocketInterface {
|
|||||||
return $this->_resource;
|
return $this->_resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls socket_accept, duplicating its self
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function __clone() {
|
public function __clone() {
|
||||||
$this->_resource = @socket_accept($this->_resource);
|
$this->_resource = @socket_accept($this->_resource);
|
||||||
|
|
||||||
@ -63,6 +60,69 @@ class Socket implements SocketInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deliver($message) {
|
||||||
|
$len = strlen($message);
|
||||||
|
|
||||||
|
do {
|
||||||
|
$sent = $this->write($message, 4);
|
||||||
|
$len -= $sent;
|
||||||
|
$message = substr($message, $sent);
|
||||||
|
} while ($len > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bind($address, $port = 0) {
|
||||||
|
if (false === @socket_bind($this->getResource(), $address, $port)) {
|
||||||
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function close() {
|
||||||
|
@socket_close($this->getResource());
|
||||||
|
unset($this->_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function connect($address, $port = 0) {
|
||||||
|
if (false === @socket_connect($this->getResource(), $address, $port)) {
|
||||||
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_option($level, $optname) {
|
||||||
|
if (false === ($res = @socket_get_option($this->getResource(), $level, $optname))) {
|
||||||
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listen($backlog = 0) {
|
||||||
|
if (false === @socket_listen($this->getResource(), $backlog)) {
|
||||||
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see http://ca3.php.net/manual/en/function.socket-recv.php
|
||||||
|
* @param string Variable to write data to
|
||||||
|
* @param int Number of bytes to read
|
||||||
|
* @param int
|
||||||
|
* @return int Number of bytes received
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function recv(&$buf, $len, $flags) {
|
||||||
|
if (false === ($bytes = @socket_recv($this->_resource, $buf, $len, $flags))) {
|
||||||
|
throw new Exception($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $bytes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since PHP is retarded and their golden hammer, the array, doesn't implement any interfaces I have to hackishly overload socket_select
|
* Since PHP is retarded and their golden hammer, the array, doesn't implement any interfaces I have to hackishly overload socket_select
|
||||||
* @see http://ca3.php.net/manual/en/function.socket-select.php
|
* @see http://ca3.php.net/manual/en/function.socket-select.php
|
||||||
@ -88,31 +148,44 @@ class Socket implements SocketInterface {
|
|||||||
return $num;
|
return $num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function set_block() {
|
||||||
* @todo Do loop to make sure entire buffer is sent to client
|
if (false === @socket_set_block($this->getResource())) {
|
||||||
*/
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_nonblock() {
|
||||||
|
if (false === @socket_set_nonblock($this->getResource())) {
|
||||||
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_option($level, $optname, $optval) {
|
||||||
|
if (false === @socket_set_option($this->getResource(), $level, $optname, $optval)) {
|
||||||
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shutdown($how = 2) {
|
||||||
|
if (false === @socket_shutdown($this->getResource(), $how)) {
|
||||||
|
throw new Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function write($buffer, $length = 0) {
|
public function write($buffer, $length = 0) {
|
||||||
return $this->__call('write', array($buffer, $length));
|
if (false === ($res = @socket_write($this->getResource(), $buffer, $length))) {
|
||||||
|
throw new Exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close() {
|
return $res;
|
||||||
return $this->__call('close', array());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see http://ca3.php.net/manual/en/function.socket-recv.php
|
|
||||||
* @param string Variable to write data to
|
|
||||||
* @param int Number of bytes to read
|
|
||||||
* @param int
|
|
||||||
* @return int Number of bytes received
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function recv(&$buf, $len, $flags) {
|
|
||||||
if (false === ($bytes = @socket_recv($this->_resource, $buf, $len, $flags))) {
|
|
||||||
throw new Exception($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $bytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,32 +249,4 @@ class Socket implements SocketInterface {
|
|||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Call all the socket_ functions (without passing the resource) through this
|
|
||||||
* @see http://ca3.php.net/manual/en/ref.sockets.php
|
|
||||||
* @param string
|
|
||||||
* @param array
|
|
||||||
* @return mixed
|
|
||||||
* @throws Exception
|
|
||||||
* @throws \BadMethodCallException
|
|
||||||
*/
|
|
||||||
public function __call($method, $arguments) {
|
|
||||||
if (function_exists('socket_' . $method)) {
|
|
||||||
// onBeforeMethod
|
|
||||||
|
|
||||||
array_unshift($arguments, $this->_resource);
|
|
||||||
$result = @call_user_func_array('socket_' . $method, $arguments);
|
|
||||||
|
|
||||||
if (false === $result) {
|
|
||||||
throw new Exception($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// onAfterMethod
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \BadMethodCallException("{$method} is not a valid socket function");
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -11,11 +11,63 @@ interface SocketInterface {
|
|||||||
function getResource();
|
function getResource();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send text to the client on the other end of the socket
|
* Return the unique ID of this socket instance
|
||||||
|
*/
|
||||||
|
function __toString();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls socket_accept, duplicating its self
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
function __clone();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message through the socket. This writes to the buffer until the entire message is delivered
|
||||||
|
* @param string Your message to send to the socket
|
||||||
|
* @return null
|
||||||
|
* @throws Exception
|
||||||
|
* @see write
|
||||||
|
*/
|
||||||
|
function deliver($message);
|
||||||
|
|
||||||
|
// Not sure if I'll implement this or leave it only in clone
|
||||||
|
// function accept();
|
||||||
|
|
||||||
|
/**
|
||||||
* @param string
|
* @param string
|
||||||
* @param int
|
* @param int
|
||||||
|
* @return SocketInterface
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
function write($buffer, $length = 0);
|
function bind($address, $port = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the open connection to the client/socket
|
||||||
|
*/
|
||||||
|
function close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string
|
||||||
|
* @param int
|
||||||
|
* @return SocketInterface
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
function connect($address, $port = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int
|
||||||
|
* @param int
|
||||||
|
* @return mixed
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
function get_option($level, $optname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int
|
||||||
|
* @return SocketInterface
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
function listen($backlog = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the client sends data to the server through the socket
|
* Called when the client sends data to the server through the socket
|
||||||
@ -24,16 +76,44 @@ interface SocketInterface {
|
|||||||
* @param int
|
* @param int
|
||||||
* @return int Number of bytes received
|
* @return int Number of bytes received
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
|
* @todo Change the pass by reference
|
||||||
*/
|
*/
|
||||||
function recv(&$buf, $len, $flags);
|
function recv(&$buf, $len, $flags);
|
||||||
|
|
||||||
/**
|
// @todo Figure out how to break this out to not do pass by reference
|
||||||
* Close the open connection to the client/socket
|
// function select(array &$read, array &$write, array &$except, $tv_sec, $tv_usec = 0);
|
||||||
*/
|
|
||||||
function close();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the unique ID of this socket instance
|
* @return SocketInterface
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
function __toString();
|
function set_block();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SocketInterface
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
function set_nonblock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int
|
||||||
|
* @param int
|
||||||
|
* @param mixed
|
||||||
|
* @return SocketInterface
|
||||||
|
*/
|
||||||
|
function set_option($level, $optname, $optval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int
|
||||||
|
* @return SocketInterface
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
function shutdown($how = 2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send text to the client on the other end of the socket
|
||||||
|
* @param string
|
||||||
|
* @param int
|
||||||
|
*/
|
||||||
|
function write($buffer, $length = 0);
|
||||||
}
|
}
|
@ -14,10 +14,7 @@ class FakeSocket extends RealSocket {
|
|||||||
return '1';
|
return '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function accept() {
|
public function bind($address, $port = 0) {
|
||||||
}
|
|
||||||
|
|
||||||
public function bind($address, $port) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close() {
|
public function close() {
|
||||||
|
@ -39,11 +39,6 @@ class SocketTest extends \PHPUnit_Framework_TestCase {
|
|||||||
$socket->close();
|
$socket->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidSocketCall() {
|
|
||||||
$this->setExpectedException('\\BadMethodCallException');
|
|
||||||
$this->_socket->fake_method();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function asArrayProvider() {
|
public function asArrayProvider() {
|
||||||
return array(
|
return array(
|
||||||
array(array('hello' => 'world'), array('hello' => 'world'))
|
array(array('hello' => 'world'), array('hello' => 'world'))
|
||||||
|
Loading…
Reference in New Issue
Block a user