Hoa central
Connection.php
Go to the documentation of this file.
1 <?php
2 
38 
39 use Hoa\Core;
40 use Hoa\Socket;
41 use Hoa\Stream;
42 
51 abstract class Connection
52  extends Stream
53  implements Stream\IStream\In,
56  \Iterator
57 {
63  protected $_socket = null;
64 
70  protected $_timeout = 30;
71 
77  protected $_flag = 0;
78 
84  protected $_context = null;
85 
91  protected $_nodeName = '\Hoa\Socket\Node';
92 
98  protected $_node = null;
99 
105  protected $_nodes = [];
106 
112  protected $_quiet = false;
113 
119  protected $_mute = false;
120 
126  protected $_disconnect = true;
127 
133  protected $_remote = false;
134 
140  protected $_remoteAddress = null;
141 
147  protected $_iterator = [];
148 
149 
150 
161  public function __construct($socket, $timeout, $flag, $context = null)
162  {
163 
164  // Children could setSocket() before __construct.
165  if (null !== $socket) {
166  $this->setSocket($socket);
167  }
168 
169  $this->setTimeout($timeout);
170  $this->setFlag($flag);
171  $this->setContext($context);
172 
173  return;
174  }
175 
181  public function connect()
182  {
183  parent::__construct(
184  $this->getSocket()->__toString(),
185  $this->getContext()
186  );
187  $this->_disconnect = false;
188 
189  return $this;
190  }
191 
197  abstract public function select();
198 
205  abstract public function consider(Connection $other);
206 
213  abstract public function is(Connection $connection);
214 
220  protected function _current()
221  {
222  $current = current($this->_iterator);
223  $this->_setStream($current);
224 
225  return $current;
226  }
227 
233  //abstract public function current ( );
234 
240  public function key()
241  {
242  return key($this->_iterator);
243  }
244 
251  public function next()
252  {
253  return next($this->_iterator);
254  }
255 
261  public function rewind()
262  {
263  return reset($this->_iterator);
264  }
265 
272  public function valid()
273  {
274  if (empty($this->_iterator)) {
275  return false;
276  }
277 
278  $key = key($this->_iterator);
279  $return = (bool) next($this->_iterator);
280  prev($this->_iterator);
281 
282  if (false === $return) {
283  end($this->_iterator);
284  if ($key === key($this->_iterator)) {
285  $return = true;
286  } else {
287  $this->_iterator = [];
288  }
289  }
290 
291  return $return;
292  }
293 
299  public function quiet()
300  {
301  return $this->_quiet =
302  stream_socket_shutdown($this->getStream(), STREAM_SHUT_RD);
303  }
304 
310  public function mute()
311  {
312  return $this->_mute =
313  stream_socket_shutdown($this->getStream(), STREAM_SHUT_WR);
314  }
315 
321  public function quietAndMute()
322  {
323  return $this->_disconnect =
324  stream_socket_shutdown($this->getStream(), STREAM_SHUT_RDWR);
325  }
326 
332  public function disconnect()
333  {
334  $this->_disconnect = $this->close();
335 
336  return;
337  }
338 
345  protected function setSocket($socket)
346  {
347  $old = $this->_socket;
348  $this->_socket = new Socket($socket);
349 
350  return $old;
351  }
352 
359  protected function setTimeout($timeout)
360  {
361  $old = $this->_timeout;
362  $this->_timeout = $timeout;
363 
364  return $old;
365  }
366 
373  protected function setFlag($flag)
374  {
375  $old = $this->_flag;
376  $this->_flag = $flag;
377 
378  return $old;
379  }
380 
387  protected function setContext($context)
388  {
389  $old = $this->_context;
390  $this->_context = $context;
391 
392  return $old;
393  }
394 
401  public function setNodeName($node)
402  {
403  $old = $this->_nodeName;
404  $this->_nodeName = $node;
405 
406  return $old;
407  }
408 
415  public function considerRemoteAddress($consider)
416  {
417  $old = $this->_remote;
418  $this->_remote = $consider;
419 
420  return $old;
421  }
422 
433  public function enableEncryption(
434  $enable,
435  $type = null,
436  $sessionStream = null
437  ) {
438  $currentNode = $this->getCurrentNode();
439 
440  if (null === $currentNode) {
441  return false;
442  }
443 
444  if (null === $type &&
445  null === $type = $currentNode->getEncryptionType()) {
446  return stream_socket_enable_crypto($this->getStream(), $enable);
447  }
448 
449  $currentNode->setEncryptionType($type);
450 
451  if (null === $sessionStream) {
452  return stream_socket_enable_crypto(
453  $this->getStream(),
454  $enable,
455  $type
456  );
457  }
458 
459  return stream_socket_enable_crypto(
460  $this->getStream(),
461  $enable,
462  $type,
463  $sessionStream
464  );
465  }
466 
472  public function isEncrypted()
473  {
474  $currentNode = $this->getCurrentNode();
475 
476  if (null === $currentNode) {
477  return false;
478  }
479 
480  return null !== $currentNode->getEncryptionType();
481  }
482 
488  public function getSocket()
489  {
490  return $this->_socket;
491  }
492 
498  public function getTimeout()
499  {
500  return $this->_timeout;
501  }
502 
508  public function getFlag()
509  {
510  return $this->_flag;
511  }
512 
518  public function getContext()
519  {
520  return $this->_context;
521  }
522 
528  public function getNodeName()
529  {
530  return $this->_nodeName;
531  }
532 
539  protected function getNodeId($resource)
540  {
541  return md5((int) $resource);
542  }
543 
549  public function getCurrentNode()
550  {
551  return $this->_node;
552  }
553 
559  public function getNodes()
560  {
561  return $this->_nodes;
562  }
563 
569  public function isQuiet()
570  {
571  return $this->_quiet;
572  }
573 
579  public function isMute()
580  {
581  return $this->_mute;
582  }
583 
589  public function isDisconnected()
590  {
591  return false !== $this->_disconnect;
592  }
593 
599  public function isRemoteAddressConsidered()
600  {
601  return $this->_remote;
602  }
603 
609  public function getRemoteAddress()
610  {
611  return $this->_remoteAddress;
612  }
613 
623  public function read($length)
624  {
625  if (null === $this->getStream()) {
626  throw new Socket\Exception(
627  'Cannot read because socket is not established, ' .
628  'i.e. not connected.',
629  0
630  );
631  }
632 
633  if (0 > $length) {
634  throw new Socket\Exception(
635  'Length must be greater than 0, given %d.',
636  1,
637  $length
638  );
639  }
640 
641  if (true === $this->isEncrypted()) {
642  return fread($this->getStream(), $length);
643  }
644 
645  if (false === $this->isRemoteAddressConsidered()) {
646  return stream_socket_recvfrom($this->getStream(), $length);
647  }
648 
649  $out = stream_socket_recvfrom(
650  $this->getStream(),
651  $length,
652  0,
653  $address
654  );
655  $this->_remoteAddress = !empty($address) ? $address : null;
656 
657  return $out;
658  }
659 
666  public function readString($length)
667  {
668  return $this->read($length);
669  }
670 
677  public function readCharacter()
678  {
679  return $this->read(1);
680  }
681 
687  public function readBoolean()
688  {
689  return (bool) $this->read(1);
690  }
691 
698  public function readInteger($length = 1)
699  {
700  return (int) $this->read($length);
701  }
702 
709  public function readFloat($length = 1)
710  {
711  return (float) $this->read($length);
712  }
713 
721  public function readArray($format = null)
722  {
723  return $this->scanf($format);
724  }
725 
731  public function readLine()
732  {
733  if (true === $this->isEncrypted()) {
734  return rtrim(fgets($this->getStream(), 1 << 15), "\n");
735  }
736 
737  return stream_get_line($this->getStream(), 1 << 15, "\n");
738  }
739 
746  public function readAll($offset = -1)
747  {
748  return stream_get_contents($this->getStream());
749  }
750 
757  public function scanf($format)
758  {
759  return sscanf($this->readAll(), $format);
760  }
761 
770  public function write($string, $length)
771  {
772  if (null === $this->getStream()) {
773  throw new Socket\Exception(
774  'Cannot write because socket is not established, ' .
775  'i.e. not connected.',
776  2
777  );
778  }
779 
780  if (0 > $length) {
781  throw new Socket\Exception(
782  'Length must be greater than 0, given %d.',
783  3,
784  $length
785  );
786  }
787 
788  if (strlen($string) > $length) {
789  $string = substr($string, 0, $length);
790  }
791 
792  if (true === $this->isEncrypted()) {
793  $out = fwrite($this->getStream(), $string, $length);
794  } else {
795  if (false === $this->isRemoteAddressConsidered() ||
796  null === $remote = $this->getRemoteAddress()) {
797  $out = @stream_socket_sendto($this->getStream(), $string);
798  } else {
799  $out = @stream_socket_sendto(
800  $this->getStream(),
801  $string,
802  0,
803  $remote
804  );
805  }
806  }
807 
808  if (-1 === $out) {
809  throw new Socket\Exception('Pipe is broken, cannot write data.', 4);
810  }
811 
812  return $out;
813  }
814 
821  public function writeString($string)
822  {
823  $string = (string) $string;
824 
825  return $this->write($string, strlen($string));
826  }
827 
834  public function writeCharacter($char)
835  {
836  return $this->write((string) $char[0], 1);
837  }
838 
845  public function writeBoolean($boolean)
846  {
847  return $this->write((string) (bool) $boolean, 1);
848  }
849 
856  public function writeInteger($integer)
857  {
858  $integer = (string) (int) $integer;
859 
860  return $this->write($integer, strlen($integer));
861  }
862 
869  public function writeFloat($float)
870  {
871  $float = (string) (float) $float;
872 
873  return $this->write($float, strlen($float));
874  }
875 
882  public function writeLine($line)
883  {
884  if (false === $n = strpos($line, "\n")) {
885  return $this->write($line . "\n", strlen($line) + 1);
886  }
887 
888  ++$n;
889 
890  return $this->write(substr($line, 0, $n), $n);
891  }
892 
899  public function writeArray(Array $array)
900  {
901  $array = serialize($array);
902 
903  return $this->write($array, strlen($array));
904  }
905 
912  public function writeAll($string)
913  {
914  return $this->write($string, strlen($string));
915  }
916 
923  public function truncate($size)
924  {
925  return false;
926  }
927 
933  public function eof()
934  {
935  return feof($this->getStream());
936  }
937 
943  public function getBasename()
944  {
945  return basename($this->getSocket()->__toString());
946  }
947 
953  public function getDirname()
954  {
955  return dirname($this->getSocket()->__toString());
956  }
957 }
958 
962 Core\Consistency::flexEntity('Hoa\Socket\Connection\Connection');
__construct($socket, $timeout, $flag, $context=null)
Definition: Connection.php:161
_setStream($stream)
Definition: Stream.php:399
is(Connection $connection)
enableEncryption($enable, $type=null, $sessionStream=null)
Definition: Connection.php:433