vendor/stomp-php/stomp-php/src/Protocol/Protocol.php line 70

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Stomp package.
  4.  *
  5.  * For the full copyright and license information, please view the LICENSE
  6.  * file that was distributed with this source code.
  7.  */
  8. namespace Stomp\Protocol;
  9. use Stomp\Exception\StompException;
  10. use Stomp\Transport\Frame;
  11. /**
  12.  * Stomp base protocol
  13.  *
  14.  *
  15.  * @package Stomp
  16.  * @author Hiram Chirino <hiram@hiramchirino.com>
  17.  * @author Dejan Bosanac <dejan@nighttale.net>
  18.  * @author Michael Caplan <mcaplan@labnet.net>
  19.  * @author Jens Radtke <swefl.oss@fin-sn.de>
  20.  */
  21. class Protocol
  22. {
  23.     /**
  24.      * Client id used for durable subscriptions
  25.      *
  26.      * @var string
  27.      */
  28.     private $clientId;
  29.     /**
  30.      * @var string
  31.      */
  32.     private $version;
  33.     /**
  34.      * Server Version
  35.      *
  36.      * @var string
  37.      */
  38.     private $server;
  39.     /**
  40.      * Setup stomp protocol with configuration.
  41.      *
  42.      * @param string $clientId
  43.      * @param string $version
  44.      * @param string $server
  45.      */
  46.     public function __construct($clientId$version Version::VERSION_1_0$server null)
  47.     {
  48.         $this->clientId $clientId;
  49.         $this->server $server;
  50.         $this->version $version;
  51.     }
  52.     /**
  53.      * Get the connect frame
  54.      *
  55.      * @param string $login
  56.      * @param string $passcode
  57.      * @param array $versions
  58.      * @param string $host
  59.      * @param int[] $heartbeat
  60.      * @return \Stomp\Transport\Frame
  61.      */
  62.     final public function getConnectFrame(
  63.         $login '',
  64.         $passcode '',
  65.         array $versions = [],
  66.         $host null,
  67.         $heartbeat = [00]
  68.     ) {
  69.         $frame $this->createFrame('CONNECT');
  70.         $frame->legacyMode(true);
  71.         if ($login || $passcode) {
  72.             $frame->addHeaders(['login' => $login'passcode' => $passcode]);
  73.         }
  74.         if ($this->hasClientId()) {
  75.             $frame['client-id'] = $this->getClientId();
  76.         }
  77.         if (!empty($versions)) {
  78.             $frame['accept-version'] = implode(','$versions);
  79.         }
  80.         $frame['host'] = $host;
  81.         $frame['heart-beat'] = $heartbeat[0] . ',' $heartbeat[1];
  82.         return $frame;
  83.     }
  84.     /**
  85.      * Get subscribe frame.
  86.      *
  87.      * @param string $destination
  88.      * @param string $subscriptionId
  89.      * @param string $ack
  90.      * @param string $selector
  91.      * @return \Stomp\Transport\Frame
  92.      * @throws StompException;
  93.      */
  94.     public function getSubscribeFrame($destination$subscriptionId null$ack 'auto'$selector null)
  95.     {
  96.         // validate ACK types per spec
  97.         // https://stomp.github.io/stomp-specification-1.0.html#frame-ACK
  98.         // https://stomp.github.io/stomp-specification-1.1.html#ACK
  99.         // https://stomp.github.io/stomp-specification-1.2.html#ACK
  100.         if ($this->hasVersion(Version::VERSION_1_1)) {
  101.             $validAcks = ['auto''client''client-individual'];
  102.         } else {
  103.             $validAcks = ['auto''client'];
  104.         }
  105.         if (!in_array($ack$validAcks)) {
  106.             throw new StompException(
  107.                 sprintf(
  108.                     '"%s" is not a valid ack value for STOMP %s. A valid value is one of %s',
  109.                     $ack,
  110.                     $this->version,
  111.                     implode(','$validAcks)
  112.                 )
  113.             );
  114.         }
  115.         
  116.         $frame $this->createFrame('SUBSCRIBE');
  117.         $frame['destination'] = $destination;
  118.         $frame['ack'] = $ack;
  119.         $frame['id'] = $subscriptionId;
  120.         $frame['selector'] = $selector;
  121.         return $frame;
  122.     }
  123.     /**
  124.      * Get unsubscribe frame.
  125.      *
  126.      * @param string $destination
  127.      * @param string $subscriptionId
  128.      * @return \Stomp\Transport\Frame
  129.      */
  130.     public function getUnsubscribeFrame($destination$subscriptionId null)
  131.     {
  132.         $frame $this->createFrame('UNSUBSCRIBE');
  133.         $frame['destination'] = $destination;
  134.         $frame['id'] = $subscriptionId;
  135.         return $frame;
  136.     }
  137.     /**
  138.      * Get transaction begin frame.
  139.      *
  140.      * @param string $transactionId
  141.      * @return \Stomp\Transport\Frame
  142.      */
  143.     public function getBeginFrame($transactionId null)
  144.     {
  145.         $frame $this->createFrame('BEGIN');
  146.         $frame['transaction'] = $transactionId;
  147.         return $frame;
  148.     }
  149.     /**
  150.      * Get transaction commit frame.
  151.      *
  152.      * @param string $transactionId
  153.      * @return \Stomp\Transport\Frame
  154.      */
  155.     public function getCommitFrame($transactionId null)
  156.     {
  157.         $frame $this->createFrame('COMMIT');
  158.         $frame['transaction'] = $transactionId;
  159.         return $frame;
  160.     }
  161.     /**
  162.      * Get transaction abort frame.
  163.      *
  164.      * @param string $transactionId
  165.      * @return \Stomp\Transport\Frame
  166.      */
  167.     public function getAbortFrame($transactionId null)
  168.     {
  169.         $frame $this->createFrame('ABORT');
  170.         $frame['transaction'] = $transactionId;
  171.         return $frame;
  172.     }
  173.     /**
  174.      * Get message acknowledge frame.
  175.      *
  176.      * @param Frame $frame
  177.      * @param string $transactionId
  178.      * @return Frame
  179.      */
  180.     public function getAckFrame(Frame $frame$transactionId null)
  181.     {
  182.         $ack $this->createFrame('ACK');
  183.         $ack['transaction'] = $transactionId;
  184.         if ($this->hasVersion(Version::VERSION_1_2)) {
  185.             if (isset($frame['ack'])) {
  186.                 $ack['id'] = $frame['ack'];
  187.             } else {
  188.                 $ack['id'] = $frame->getMessageId();
  189.             }
  190.         } else {
  191.             $ack['message-id'] = $frame->getMessageId();
  192.             if ($this->hasVersion(Version::VERSION_1_1)) {
  193.                 $ack['subscription'] = $frame['subscription'];
  194.             }
  195.         }
  196.         return $ack;
  197.     }
  198.     /**
  199.      * Get message not acknowledge frame.
  200.      *
  201.      * @param \Stomp\Transport\Frame $frame
  202.      * @param string $transactionId
  203.      * @param bool $requeue Requeue header
  204.      * @return \Stomp\Transport\Frame
  205.      * @throws StompException
  206.      * @throws \LogicException
  207.      */
  208.     public function getNackFrame(Frame $frame$transactionId null$requeue null)
  209.     {
  210.         if ($requeue !== null) {
  211.             throw new \LogicException('requeue header not supported');
  212.         }
  213.         if ($this->version === Version::VERSION_1_0) {
  214.             throw new StompException('Stomp Version 1.0 has no support for NACK Frames.');
  215.         }
  216.         $nack $this->createFrame('NACK');
  217.         $nack['transaction'] = $transactionId;
  218.         if ($this->hasVersion(Version::VERSION_1_2)) {
  219.             $nack['id'] = $frame->getMessageId();
  220.         } else {
  221.             $nack['message-id'] = $frame->getMessageId();
  222.             if ($this->hasVersion(Version::VERSION_1_1)) {
  223.                 $nack['subscription'] = $frame['subscription'];
  224.             }
  225.         }
  226.         $nack['message-id'] = $frame->getMessageId();
  227.         return $nack;
  228.     }
  229.     /**
  230.      * Get the disconnect frame.
  231.      *
  232.      * @return \Stomp\Transport\Frame
  233.      */
  234.     public function getDisconnectFrame()
  235.     {
  236.         $frame $this->createFrame('DISCONNECT');
  237.         if ($this->hasClientId()) {
  238.             $frame['client-id'] = $this->getClientId();
  239.         }
  240.         return $frame;
  241.     }
  242.     /**
  243.      * Client Id is set
  244.      *
  245.      * @return boolean
  246.      */
  247.     public function hasClientId()
  248.     {
  249.         return (boolean) $this->clientId;
  250.     }
  251.     /**
  252.      * Client Id is set
  253.      *
  254.      * @return string
  255.      */
  256.     public function getClientId()
  257.     {
  258.         return $this->clientId;
  259.     }
  260.     /**
  261.      * Stomp Version
  262.      *
  263.      * @return string
  264.      */
  265.     public function getVersion()
  266.     {
  267.         return $this->version;
  268.     }
  269.     /**
  270.      * Server Version Info
  271.      *
  272.      * @return string
  273.      */
  274.     public function getServer()
  275.     {
  276.         return $this->server;
  277.     }
  278.     /**
  279.      * Checks if given version is included (equal or lower) in active protocol version.
  280.      *
  281.      * @param string $version
  282.      * @return bool
  283.      */
  284.     public function hasVersion($version)
  285.     {
  286.         return version_compare($this->version$version'>=');
  287.     }
  288.     /**
  289.      * Creates a Frame according to the detected STOMP version.
  290.      *
  291.      * @param string $command
  292.      * @return Frame
  293.      */
  294.     protected function createFrame($command)
  295.     {
  296.         $frame = new Frame($command);
  297.         if ($this->version === Version::VERSION_1_0) {
  298.             $frame->legacyMode(true);
  299.         }
  300.         return $frame;
  301.     }
  302. }