├── .gitattributes ├── .github ├── CHANGELOG.md └── workflows │ └── continuous-integration.yml ├── .gitignore ├── composer.json ├── phpstan.neon ├── phpunit.xml ├── psalm.xml └── src ├── Buffer.php ├── Channel.php ├── Client.php ├── CommandWaitQueue.php ├── Config.php ├── Connection.php ├── Constants.php ├── Consumer.php ├── Events.php ├── Exception ├── ChannelException.php ├── ClassInvalid.php ├── ClientException.php ├── ConfigurationException.php ├── ConnectionException.php ├── MethodInvalid.php ├── ProtocolException.php └── RidgeException.php ├── Message.php ├── MessageReceiver.php ├── Parser.php ├── Properties.php ├── Protocol ├── AbstractFrame.php ├── AcknowledgmentFrame.php ├── BasicAckFrame.php ├── BasicCancelFrame.php ├── BasicCancelOkFrame.php ├── BasicConsumeFrame.php ├── BasicConsumeOkFrame.php ├── BasicDeliverFrame.php ├── BasicGetEmptyFrame.php ├── BasicGetFrame.php ├── BasicGetOkFrame.php ├── BasicNackFrame.php ├── BasicPublishFrame.php ├── BasicQosFrame.php ├── BasicQosOkFrame.php ├── BasicRecoverAsyncFrame.php ├── BasicRecoverFrame.php ├── BasicRecoverOkFrame.php ├── BasicRejectFrame.php ├── BasicReturnFrame.php ├── ChannelCloseFrame.php ├── ChannelCloseOkFrame.php ├── ChannelFlowFrame.php ├── ChannelFlowOkFrame.php ├── ChannelOpenFrame.php ├── ChannelOpenOkFrame.php ├── ConfirmSelectFrame.php ├── ConfirmSelectOkFrame.php ├── ConnectionBlockedFrame.php ├── ConnectionCloseFrame.php ├── ConnectionCloseOkFrame.php ├── ConnectionOpenFrame.php ├── ConnectionOpenOkFrame.php ├── ConnectionSecureFrame.php ├── ConnectionSecureOkFrame.php ├── ConnectionStartFrame.php ├── ConnectionStartOkFrame.php ├── ConnectionTuneFrame.php ├── ConnectionTuneOkFrame.php ├── ConnectionUnblockedFrame.php ├── ContentBodyFrame.php ├── ContentHeaderFrame.php ├── ExchangeBindFrame.php ├── ExchangeBindOkFrame.php ├── ExchangeDeclareFrame.php ├── ExchangeDeclareOkFrame.php ├── ExchangeDeleteFrame.php ├── ExchangeDeleteOkFrame.php ├── ExchangeUnbindFrame.php ├── ExchangeUnbindOkFrame.php ├── HeartbeatFrame.php ├── MessageFrame.php ├── MethodFrame.php ├── QueueBindFrame.php ├── QueueBindOkFrame.php ├── QueueDeclareFrame.php ├── QueueDeclareOkFrame.php ├── QueueDeleteFrame.php ├── QueueDeleteOkFrame.php ├── QueuePurgeFrame.php ├── QueuePurgeOkFrame.php ├── QueueUnbindFrame.php ├── QueueUnbindOkFrame.php ├── TxCommitFrame.php ├── TxCommitOkFrame.php ├── TxRollbackFrame.php ├── TxRollbackOkFrame.php ├── TxSelectFrame.php └── TxSelectOkFrame.php └── Queue.php /.gitattributes: -------------------------------------------------------------------------------- 1 | /benchmarks export-ignore 2 | /examples export-ignore 3 | /tests export-ignore 4 | CONDUCT.md export-ignore 5 | CONTRIBUTING.md export-ignore 6 | ISSUE_TEMPLATE.md export-ignore 7 | LICENSE.md export-ignore 8 | PULL_REQUEST_TEMPLATE.md export-ignore 9 | README.md export-ignore 10 | -------------------------------------------------------------------------------- /.github/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All Notable changes to `Ridge` will be documented in this file. 4 | 5 | Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. 6 | 7 | ## NEXT - YYYY-MM-DD 8 | 9 | ### Added 10 | - Nothing 11 | 12 | ### Deprecated 13 | - Nothing 14 | 15 | ### Fixed 16 | - Nothing 17 | 18 | ### Removed 19 | - Nothing 20 | 21 | ### Security 22 | - Nothing 23 | -------------------------------------------------------------------------------- /.github/workflows/continuous-integration.yml: -------------------------------------------------------------------------------- 1 | name: "Continuous Integration" 2 | 3 | on: [ push, pull_request ] 4 | 5 | jobs: 6 | psalm: 7 | name: Psalm 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | 13 | - name: Install PHP 14 | uses: shivammathur/setup-php@v2 15 | with: 16 | php-version: 8.1 17 | coverage: none 18 | tools: composer:v2 19 | 20 | - name: Install dependencies with composer 21 | run: composer install -ov 22 | 23 | - name: Run vimeo/psalm 24 | run: ./vendor/bin/psalm --config=psalm.xml --shepherd 25 | 26 | phpstan: 27 | name: PHPStan 28 | runs-on: ubuntu-latest 29 | steps: 30 | - name: Checkout 31 | uses: actions/checkout@v2 32 | 33 | - name: Install PHP 34 | uses: shivammathur/setup-php@v2 35 | with: 36 | php-version: 8.1 37 | coverage: none 38 | tools: composer:v2 39 | 40 | - name: Install dependencies with composer 41 | run: composer install -ov 42 | 43 | - name: Run phpstan/phpstan 44 | run: ./vendor/bin/phpstan analyse src --level 9 45 | 46 | phpunit: 47 | name: PHPUnit 48 | 49 | runs-on: ubuntu-latest 50 | services: 51 | rabbitmq: 52 | image: rabbitmq:alpine 53 | ports: 54 | - 5672:5672 55 | env: 56 | RABBITMQ_DEFAULT_USER: guest 57 | RABBITMQ_DEFAULT_PASS: guest 58 | options: --health-cmd "rabbitmqctl node_health_check" --health-interval 10s --health-timeout 5s --health-retries 5 59 | 60 | env: 61 | PHP_EXTENSIONS: mbstring, dom, intl, json, libxml, xml, xmlwriter, sockets 62 | PHP_INI_VALUES: assert.exception=1, zend.assertions=1 63 | 64 | steps: 65 | - name: Checkout 66 | uses: actions/checkout@v2 67 | 68 | - name: Install PHP with extensions 69 | uses: shivammathur/setup-php@v2 70 | with: 71 | php-version: 8.1 72 | extensions: ${{ env.PHP_EXTENSIONS }} 73 | ini-values: ${{ env.PHP_INI_VALUES }} 74 | tools: composer:v2 75 | 76 | - name: Install dependencies 77 | run: composer update -ov 78 | 79 | - name: Await 80 | uses: jakejarvis/wait-action@master 81 | 82 | - name: Run tests with phpunit 83 | run: php ./vendor/bin/phpunit --configuration ./phpunit.xml -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .phpunit.result.cache 2 | /.idea 3 | /vendor 4 | /build 5 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phpinnacle/ridge", 3 | "type": "library", 4 | "description": "PHPinnacle async AMQP client", 5 | "keywords": [ 6 | "phpinnacle", 7 | "async", 8 | "amqp" 9 | ], 10 | "homepage": "https://github.com/phpinnacle/ridge", 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "PHPinnacle", 15 | "email": "dev@phpinnacle.com", 16 | "homepage": "https://phpinnacle.com", 17 | "role": "Developer" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=8.1", 22 | "amphp/amp": "v2.6.*", 23 | "amphp/socket": "v1.2.*", 24 | "phpinnacle/buffer": "v1.2.*", 25 | "evenement/evenement": "v3.0.*" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "10.* || 11.*", 29 | "vimeo/psalm": "5.*", 30 | "phpstan/phpstan": "^1.10" 31 | }, 32 | "prefer-stable": true, 33 | "autoload": { 34 | "psr-4": { 35 | "PHPinnacle\\Ridge\\": "src" 36 | } 37 | }, 38 | "autoload-dev": { 39 | "psr-4": { 40 | "PHPinnacle\\Ridge\\Tests\\": "tests" 41 | } 42 | }, 43 | "scripts": { 44 | "psalm": "./vendor/bin/psalm --config=psalm.xml", 45 | "phpstan": "./vendor/bin/phpstan analyse src --level 9", 46 | "tests": "./vendor/bin/phpunit --configuration phpunit.xml", 47 | "coverage": "./vendor/bin/phpunit --configuration phpunit.xml --coverage-html ./coverage --verbose" 48 | }, 49 | "extra": { 50 | "branch-alias": { 51 | "dev-master": "1.0-dev" 52 | } 53 | }, 54 | "config": { 55 | "sort-packages": true, 56 | "optimize-autoloader": true, 57 | "allow-plugins": { 58 | "composer/package-versions-deprecated": false 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | checkMissingIterableValueType: false 3 | checkGenericClassInNonGenericObjectType: false 4 | 5 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ./tests/ 18 | 19 | 20 | 21 | 22 | ./ 23 | 24 | 25 | ./tests 26 | ./vendor 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Buffer.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use PHPinnacle\Buffer\ByteBuffer; 16 | 17 | final class Buffer extends ByteBuffer 18 | { 19 | public function appendString(string $value): self 20 | { 21 | $this 22 | ->appendUint8(\strlen($value)) 23 | ->append($value); 24 | 25 | return $this; 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public function consumeString(): string 32 | { 33 | return $this->consume($this->consumeUint8()); 34 | } 35 | 36 | public function appendText(string $value): self 37 | { 38 | $this 39 | ->appendUint32(\strlen($value)) 40 | ->append($value); 41 | 42 | return $this; 43 | } 44 | 45 | /** 46 | * @throws \PHPinnacle\Buffer\BufferOverflow 47 | */ 48 | public function consumeText(): string 49 | { 50 | return $this->consume($this->consumeUint32()); 51 | } 52 | 53 | public function appendBits(array $bits): self 54 | { 55 | $value = 0; 56 | 57 | /** 58 | * @var int $n 59 | * @var bool $bit 60 | */ 61 | foreach ($bits as $n => $bit) { 62 | $bit = $bit ? 1 : 0; 63 | $value |= $bit << $n; 64 | } 65 | 66 | $this->appendUint8($value); 67 | 68 | return $this; 69 | } 70 | 71 | /** 72 | * @throws \PHPinnacle\Buffer\BufferOverflow 73 | */ 74 | public function consumeBits(int $n): array 75 | { 76 | $bits = []; 77 | $value = $this->consumeUint8(); 78 | 79 | for ($i = 0; $i < $n; ++$i) { 80 | $bits[] = ($value & (1 << $i)) > 0; 81 | } 82 | 83 | return $bits; 84 | } 85 | 86 | public function appendTimestamp(\DateTimeInterface $value): self 87 | { 88 | $this->appendUint64($value->getTimestamp()); 89 | 90 | return $this; 91 | } 92 | 93 | public function consumeTimestamp(): \DateTimeInterface 94 | { 95 | /** @noinspection PhpUnhandledExceptionInspection */ 96 | return new \DateTimeImmutable(\sprintf('@%s', $this->consumeUint64())); 97 | } 98 | 99 | /** 100 | * @throws \PHPinnacle\Ridge\Exception\ProtocolException 101 | */ 102 | public function appendTable(array $table): self 103 | { 104 | $buffer = new self(); 105 | 106 | /** 107 | * @var string|ByteBuffer $k 108 | * @var mixed $v 109 | */ 110 | foreach ($table as $k => $v) { 111 | $k = (string)$k; 112 | 113 | $buffer->appendUint8(\strlen($k)); 114 | $buffer->append($k); 115 | $buffer->appendValue($v); 116 | } 117 | 118 | $this 119 | ->appendUint32($buffer->size()) 120 | ->append($buffer); 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * @throws \PHPinnacle\Buffer\BufferOverflow 127 | */ 128 | public function consumeTable(): array 129 | { 130 | $buffer = $this->shift($this->consumeUint32()); 131 | $data = []; 132 | 133 | while (!$buffer->empty()) { 134 | $data[$buffer->consume($buffer->consumeUint8())] = $buffer->consumeValue(); 135 | } 136 | 137 | return $data; 138 | } 139 | 140 | /** 141 | * @throws \PHPinnacle\Ridge\Exception\ProtocolException 142 | */ 143 | public function appendArray(array $value): self 144 | { 145 | $buffer = new self(); 146 | 147 | /** @var mixed $v */ 148 | foreach ($value as $v) { 149 | $buffer->appendValue($v); 150 | } 151 | 152 | $this 153 | ->appendUint32($buffer->size()) 154 | ->append($buffer); 155 | 156 | return $this; 157 | } 158 | 159 | /** 160 | * @throws \PHPinnacle\Buffer\BufferOverflow 161 | */ 162 | public function consumeArray(): array 163 | { 164 | $buffer = $this->shift($this->consumeUint32()); 165 | $data = []; 166 | 167 | while (!$buffer->empty()) { 168 | $data[] = $buffer->consumeValue(); 169 | } 170 | 171 | return $data; 172 | } 173 | 174 | /** 175 | * @throws \PHPinnacle\Buffer\BufferOverflow 176 | */ 177 | public function consumeDecimal(): int 178 | { 179 | $scale = $this->consumeUint8(); 180 | $value = $this->consumeUint32(); 181 | 182 | return $value * (10 ** $scale); 183 | } 184 | 185 | /** 186 | * @throws \PHPinnacle\Buffer\BufferOverflow 187 | * @throws \PHPinnacle\Ridge\Exception\ProtocolException 188 | */ 189 | private function consumeValue(): float|\DateTimeInterface|null|array|bool|int|string 190 | { 191 | $fieldType = $this->consumeUint8(); 192 | 193 | return match ($fieldType) { 194 | Constants::FIELD_BOOLEAN => $this->consumeUint8() > 0, 195 | Constants::FIELD_SHORT_SHORT_INT => $this->consumeInt8(), 196 | Constants::FIELD_SHORT_SHORT_UINT => $this->consumeUint8(), 197 | Constants::FIELD_SHORT_INT => $this->consumeInt16(), 198 | Constants::FIELD_SHORT_UINT => $this->consumeUint16(), 199 | Constants::FIELD_LONG_INT => $this->consumeInt32(), 200 | Constants::FIELD_LONG_UINT => $this->consumeUint32(), 201 | Constants::FIELD_LONG_LONG_INT => $this->consumeInt64(), 202 | Constants::FIELD_LONG_LONG_UINT => $this->consumeUint64(), 203 | Constants::FIELD_FLOAT => $this->consumeFloat(), 204 | Constants::FIELD_DOUBLE => $this->consumeDouble(), 205 | Constants::FIELD_DECIMAL => $this->consumeDecimal(), 206 | Constants::FIELD_SHORT_STRING => $this->consume($this->consumeUint8()), 207 | Constants::FIELD_LONG_STRING => $this->consume($this->consumeUint32()), 208 | Constants::FIELD_TIMESTAMP => $this->consumeTimestamp(), 209 | Constants::FIELD_ARRAY => $this->consumeArray(), 210 | Constants::FIELD_TABLE => $this->consumeTable(), 211 | Constants::FIELD_NULL => null, 212 | default => throw Exception\ProtocolException::unknownFieldType($fieldType), 213 | }; 214 | } 215 | 216 | /** 217 | * @throws \PHPinnacle\Ridge\Exception\ProtocolException 218 | */ 219 | private function appendValue(mixed $value): void 220 | { 221 | if (\is_string($value)) { 222 | $this->appendUint8(Constants::FIELD_LONG_STRING); 223 | $this->appendText($value); 224 | 225 | return; 226 | } 227 | 228 | if (\is_int($value)) { 229 | $this->appendUint8(Constants::FIELD_LONG_INT); 230 | $this->appendInt32($value); 231 | 232 | return; 233 | } 234 | 235 | if (\is_bool($value)) { 236 | $this->appendUint8(Constants::FIELD_BOOLEAN); 237 | $this->appendUint8((int)$value); 238 | 239 | return; 240 | } 241 | 242 | if (\is_float($value)) { 243 | $this->appendUint8(Constants::FIELD_DOUBLE); 244 | $this->appendDouble($value); 245 | 246 | return; 247 | } 248 | 249 | if (\is_array($value)) { 250 | if (\array_keys($value) === \range(0, \count($value) - 1)) { 251 | $this->appendUint8(Constants::FIELD_ARRAY); 252 | $this->appendArray($value); 253 | } else { 254 | $this->appendUint8(Constants::FIELD_TABLE); 255 | $this->appendTable($value); 256 | } 257 | 258 | return; 259 | } 260 | 261 | if (\is_null($value)) { 262 | $this->appendUint8(Constants::FIELD_NULL); 263 | 264 | return; 265 | } 266 | 267 | if ($value instanceof \DateTimeInterface) { 268 | $this->appendUint8(Constants::FIELD_TIMESTAMP); 269 | $this->appendTimestamp($value); 270 | 271 | return; 272 | } 273 | 274 | throw Exception\ProtocolException::unknownValueType($value); 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use Amp\Loop; 16 | use Amp\MultiReasonException; 17 | use Evenement\EventEmitterTrait; 18 | use PHPinnacle\Ridge\Exception\ChannelException; 19 | use PHPinnacle\Ridge\Exception\ConnectionException; 20 | use function Amp\asyncCall; 21 | use function Amp\call; 22 | use Amp\Deferred; 23 | use Amp\Promise; 24 | 25 | final class Client 26 | { 27 | use EventEmitterTrait; 28 | 29 | public const EVENT_CLOSE = 'close'; 30 | 31 | private const STATE_NOT_CONNECTED = 0; 32 | private const STATE_CONNECTING = 1; 33 | private const STATE_CONNECTED = 2; 34 | private const STATE_DISCONNECTING = 3; 35 | 36 | private const CONNECTION_MONITOR_INTERVAL = 5000; 37 | 38 | /** 39 | * @var Config 40 | */ 41 | private $config; 42 | 43 | /** 44 | * @var int 45 | */ 46 | private $state = self::STATE_NOT_CONNECTED; 47 | 48 | /** 49 | * @var Channel[] 50 | */ 51 | private $channels = []; 52 | 53 | /** 54 | * @var int 55 | */ 56 | private $nextChannelId = 1; 57 | 58 | /** 59 | * @var Connection 60 | */ 61 | private $connection; 62 | 63 | /** 64 | * @var Properties 65 | */ 66 | private $properties; 67 | 68 | /** 69 | * @var string|null 70 | */ 71 | private $connectionMonitorWatcherId; 72 | 73 | private CommandWaitQueue $commandWaitQueue; 74 | 75 | public function __construct(Config $config) 76 | { 77 | $this->config = $config; 78 | $this->commandWaitQueue = new CommandWaitQueue(); 79 | $this->on(self::EVENT_CLOSE, function (\Throwable $exception = null) { 80 | if ($exception !== null) { 81 | foreach ($this->channels as $channel) { 82 | $channel->forceClose($exception); 83 | } 84 | $this->channels = []; 85 | $this->commandWaitQueue->cancel($exception); 86 | 87 | throw $exception; 88 | } 89 | }); 90 | } 91 | 92 | public static function create(string $dsn): self 93 | { 94 | return new self(Config::parse($dsn)); 95 | } 96 | 97 | /** 98 | * @throws \PHPinnacle\Ridge\Exception\ClientException 99 | */ 100 | public function properties(): Properties 101 | { 102 | if ($this->state !== self::STATE_CONNECTED) { 103 | throw Exception\ClientException::notConnected(); 104 | } 105 | 106 | return $this->properties; 107 | } 108 | 109 | /** 110 | * @return Promise 111 | * 112 | * @throws \PHPinnacle\Ridge\Exception\ClientException 113 | */ 114 | public function connect(): Promise 115 | { 116 | return call( 117 | function () { 118 | if ($this->state !== self::STATE_NOT_CONNECTED) { 119 | throw Exception\ClientException::alreadyConnected(); 120 | } 121 | 122 | $this->state = self::STATE_CONNECTING; 123 | 124 | $this->connection = new Connection($this->config->uri()); 125 | $this->connection->once(Connection::EVENT_CLOSE, function(\Throwable $exception = null) { 126 | $this->state = self::STATE_NOT_CONNECTED; 127 | $this->emit(self::EVENT_CLOSE, [$exception]); 128 | }); 129 | 130 | yield $this->connection->open( 131 | $this->config->timeout, 132 | $this->config->tcpAttempts, 133 | $this->config->tcpNoDelay 134 | ); 135 | 136 | $buffer = new Buffer; 137 | $buffer 138 | ->append('AMQP') 139 | ->appendUint8(0) 140 | ->appendUint8(0) 141 | ->appendUint8(9) 142 | ->appendUint8(1); 143 | 144 | yield $this->connection->write($buffer); 145 | 146 | yield $this->connectionStart(); 147 | yield $this->connectionTune(); 148 | yield $this->connectionOpen(); 149 | 150 | asyncCall( 151 | function () { 152 | /** @var Protocol\ConnectionCloseFrame $frame */ 153 | $frame = yield $this->await(Protocol\ConnectionCloseFrame::class); 154 | $buffer = new Buffer; 155 | $buffer 156 | ->appendUint8(1) 157 | ->appendUint16(0) 158 | ->appendUint32(4) 159 | ->appendUint16(10) 160 | ->appendUint16(51) 161 | ->appendUint8(206); 162 | 163 | $this->connection->write($buffer); 164 | $this->connection->close(); 165 | 166 | $exception = Exception\ClientException::connectionClosed($frame); 167 | 168 | $this->disableConnectionMonitor(); 169 | 170 | $this->emit(self::EVENT_CLOSE, [$exception]); 171 | } 172 | ); 173 | 174 | $this->state = self::STATE_CONNECTED; 175 | 176 | $this->connectionMonitorWatcherId = Loop::repeat( 177 | self::CONNECTION_MONITOR_INTERVAL, 178 | function(): void 179 | { 180 | if($this->connection->connected() === false) { 181 | $this->state = self::STATE_NOT_CONNECTED; 182 | $this->emit(self::EVENT_CLOSE, [Exception\ClientException::disconnected()]); 183 | } 184 | } 185 | ); 186 | } 187 | ); 188 | } 189 | 190 | /** 191 | * @psalm-suppress InvalidReturnType 192 | * @psalm-suppress InvalidReturnStatement 193 | * 194 | * @return Promise 195 | * 196 | * @throws \PHPinnacle\Ridge\Exception\ClientException 197 | */ 198 | public function disconnect(int $code = 0, string $reason = ''): Promise 199 | { 200 | $this->disableConnectionMonitor(); 201 | 202 | return call( 203 | function () use ($code, $reason) { 204 | try { 205 | if (\in_array($this->state, [self::STATE_NOT_CONNECTED, self::STATE_DISCONNECTING])) { 206 | return; 207 | } 208 | 209 | if ($this->state !== self::STATE_CONNECTED) { 210 | throw Exception\ClientException::notConnected(); 211 | } 212 | 213 | if($this->connectionMonitorWatcherId !== null){ 214 | Loop::cancel($this->connectionMonitorWatcherId); 215 | 216 | $this->connectionMonitorWatcherId = null; 217 | } 218 | 219 | $this->state = self::STATE_DISCONNECTING; 220 | 221 | if ($code === 0) { 222 | $promises = []; 223 | 224 | foreach ($this->channels as $channel) { 225 | $promises[] = $channel->close($code, $reason); 226 | } 227 | 228 | // Gracefully continue to close connection even if closing channels fails 229 | yield Promise\any($promises); 230 | $this->channels = []; 231 | } 232 | 233 | yield $this->connectionClose($code, $reason); 234 | 235 | $this->connection->close(); 236 | } 237 | finally 238 | { 239 | $this->state = self::STATE_NOT_CONNECTED; 240 | } 241 | } 242 | ); 243 | } 244 | 245 | /** 246 | * @return Promise 247 | * 248 | * @throws \PHPinnacle\Ridge\Exception\ClientException 249 | */ 250 | public function channel(): Promise 251 | { 252 | return call( 253 | function () { 254 | if ($this->state !== self::STATE_CONNECTED) { 255 | throw Exception\ClientException::notConnected(); 256 | } 257 | 258 | try { 259 | $id = $this->findChannelId(); 260 | $channel = new Channel($id, $this->connection, $this->properties); 261 | 262 | $this->channels[$id] = $channel; 263 | 264 | yield $channel->open(); 265 | yield $channel->qos($this->config->qosSize, $this->config->qosCount, $this->config->qosGlobal); 266 | 267 | asyncCall(function () use ($id) { 268 | try { 269 | $frame = yield Promise\first([ 270 | $this->await(Protocol\ChannelCloseFrame::class, $id), 271 | $this->await(Protocol\ChannelCloseOkFrame::class, $id) 272 | ]); 273 | 274 | $channel = $this->channels[$id]; 275 | unset($this->channels[$id]); 276 | 277 | if ($frame instanceof Protocol\ChannelCloseFrame) { 278 | $buffer = new Buffer; 279 | $buffer 280 | ->appendUint8(1) 281 | ->appendUint16($id) 282 | ->appendUint32(4) 283 | ->appendUint16(20) 284 | ->appendUint16(41) 285 | ->appendUint8(206); 286 | 287 | yield $this->connection->write($buffer); 288 | $channel->forceClose(new ChannelException("Channel closed: {$frame->replyText}")); 289 | } 290 | } 291 | catch (MultiReasonException $exception) { 292 | // There was an error when waiting for those frames 293 | // We should not unset the channel here because the client will clean them up 294 | // with the correct error when the connection close event triggers 295 | } 296 | 297 | $this->connection->cancel($id); 298 | }); 299 | 300 | return $channel; 301 | } 302 | catch(ConnectionException $exception) { 303 | $this->state = self::STATE_NOT_CONNECTED; 304 | 305 | throw $exception; 306 | } 307 | catch (\Throwable $error) { 308 | throw Exception\ClientException::unexpectedResponse($error); 309 | } 310 | } 311 | ); 312 | } 313 | 314 | public function isConnected(): bool 315 | { 316 | return $this->state === self::STATE_CONNECTED && $this->connection->connected(); 317 | } 318 | 319 | /** 320 | * @return Promise 321 | * 322 | * @throws \PHPinnacle\Ridge\Exception\ClientException 323 | */ 324 | private function connectionStart(): Promise 325 | { 326 | return call( 327 | function () { 328 | /** @var Protocol\ConnectionStartFrame $start */ 329 | $start = yield $this->await(Protocol\ConnectionStartFrame::class); 330 | 331 | if (!\str_contains($start->mechanisms, 'AMQPLAIN')) { 332 | throw Exception\ClientException::notSupported($start->mechanisms); 333 | } 334 | 335 | $this->properties = Properties::create($start->serverProperties); 336 | 337 | $buffer = new Buffer; 338 | $buffer 339 | ->appendTable([ 340 | 'LOGIN' => $this->config->user, 341 | 'PASSWORD' => $this->config->pass, 342 | ]) 343 | ->discard(4); 344 | 345 | $frameBuffer = new Buffer; 346 | $frameBuffer 347 | ->appendUint16(10) 348 | ->appendUint16(11) 349 | ->appendTable([]) 350 | ->appendString('AMQPLAIN') 351 | ->appendText((string)$buffer) 352 | ->appendString('en_US'); 353 | 354 | return $this->connection->method(0, $frameBuffer); 355 | } 356 | ); 357 | } 358 | 359 | /** 360 | * @return Promise 361 | */ 362 | private function connectionTune(): Promise 363 | { 364 | return call( 365 | function () { 366 | /** @var Protocol\ConnectionTuneFrame $tune */ 367 | $tune = yield $this->await(Protocol\ConnectionTuneFrame::class); 368 | 369 | $heartbeatTimeout = $this->config->heartbeat; 370 | 371 | if ($heartbeatTimeout !== 0) { 372 | $heartbeatTimeout = \min($heartbeatTimeout, $tune->heartbeat * 1000); 373 | } 374 | 375 | $maxChannel = \min($this->config->maxChannel, $tune->channelMax); 376 | $maxFrame = \min($this->config->maxFrame, $tune->frameMax); 377 | 378 | $buffer = new Buffer; 379 | $buffer 380 | ->appendUint8(1) 381 | ->appendUint16(0) 382 | ->appendUint32(12) 383 | ->appendUint16(10) 384 | ->appendUint16(31) 385 | ->appendInt16($maxChannel) 386 | ->appendInt32($maxFrame) 387 | ->appendInt16((int) ($heartbeatTimeout / 1000)) 388 | ->appendUint8(206); 389 | 390 | yield $this->connection->write($buffer); 391 | 392 | $this->properties->tune($maxChannel, $maxFrame); 393 | 394 | if ($heartbeatTimeout > 0) { 395 | $this->connection->heartbeat($heartbeatTimeout); 396 | } 397 | } 398 | ); 399 | } 400 | 401 | /** 402 | * @return Promise 403 | */ 404 | private function connectionOpen(): Promise 405 | { 406 | return call( 407 | function () { 408 | $vhost = $this->config->vhost; 409 | $capabilities = ''; 410 | $insist = false; 411 | 412 | $buffer = new Buffer; 413 | $buffer 414 | ->appendUint8(1) 415 | ->appendUint16(0) 416 | ->appendUint32(7 + \strlen($vhost) + \strlen($capabilities)) 417 | ->appendUint16(10) 418 | ->appendUint16(40) 419 | ->appendString($vhost) 420 | ->appendString($capabilities) // TODO: process server capabilities 421 | ->appendBits([$insist]) 422 | ->appendUint8(206); 423 | 424 | yield $this->connection->write($buffer); 425 | 426 | return $this->await(Protocol\ConnectionOpenOkFrame::class); 427 | } 428 | ); 429 | } 430 | 431 | /** 432 | * @return Promise 433 | */ 434 | private function connectionClose(int $code, string $reason): Promise 435 | { 436 | return call( 437 | function () use ($code, $reason) { 438 | $buffer = new Buffer; 439 | $buffer 440 | ->appendUint8(1) 441 | ->appendUint16(0) 442 | ->appendUint32(11 + \strlen($reason)) 443 | ->appendUint16(10) 444 | ->appendUint16(50) 445 | ->appendInt16($code) 446 | ->appendString($reason) 447 | ->appendInt16(0) 448 | ->appendInt16(0) 449 | ->appendUint8(206); 450 | 451 | yield $this->connection->write($buffer); 452 | 453 | return $this->await(Protocol\ConnectionCloseOkFrame::class); 454 | } 455 | ); 456 | } 457 | 458 | /** 459 | * @return int 460 | */ 461 | private function findChannelId(): int 462 | { 463 | /** first check in range [next, max] ... */ 464 | for ($id = $this->nextChannelId; $id <= $this->config->maxChannel; ++$id) { 465 | if (!isset($this->channels[$id])) { 466 | $this->nextChannelId = $id + 1; 467 | 468 | return $id; 469 | } 470 | } 471 | 472 | /** then check in range [min, next) ... */ 473 | for ($id = 1; $id < $this->nextChannelId; ++$id) { 474 | if (!isset($this->channels[$id])) { 475 | $this->nextChannelId = $id + 1; 476 | 477 | return $id; 478 | } 479 | } 480 | 481 | throw Exception\ClientException::noChannelsAvailable(); 482 | } 483 | 484 | /** 485 | * @template T of Protocol\AbstractFrame 486 | * @psalm-param class-string $frame 487 | * @psalm-return Promise 488 | */ 489 | private function await(string $frame, int $channel = 0): Promise 490 | { 491 | /** @psalm-var Deferred $deferred */ 492 | $deferred = new Deferred; 493 | $this->commandWaitQueue->add($deferred); 494 | 495 | $this->connection->subscribe( 496 | $channel, 497 | $frame, 498 | static function (Protocol\AbstractFrame $frame) use ($deferred) { 499 | /** @psalm-var T $frame */ 500 | $deferred->resolve($frame); 501 | 502 | return true; 503 | } 504 | ); 505 | 506 | return $deferred->promise(); 507 | } 508 | 509 | private function disableConnectionMonitor(): void { 510 | if($this->connectionMonitorWatcherId !== null) { 511 | 512 | Loop::cancel($this->connectionMonitorWatcherId); 513 | 514 | $this->connectionMonitorWatcherId = null; 515 | } 516 | } 517 | } 518 | -------------------------------------------------------------------------------- /src/CommandWaitQueue.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use Amp\Deferred; 16 | 17 | final class CommandWaitQueue 18 | { 19 | /** @var Deferred[] */ 20 | private array $waitingCommands = []; 21 | 22 | public function add(Deferred $deferred): void { 23 | $this->waitingCommands[spl_object_hash($deferred)] = $deferred; 24 | $deferred->promise()->onResolve(function() use ($deferred) { 25 | unset($this->waitingCommands[spl_object_hash($deferred)]); 26 | }); 27 | } 28 | 29 | public function cancel(\Throwable $throwable): void { 30 | foreach ($this->waitingCommands as $id => $deferred) { 31 | $deferred->fail($throwable); 32 | unset($this->waitingCommands[$id]); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Config.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use PHPinnacle\Ridge\Exception\ConfigurationException; 16 | 17 | final class Config 18 | { 19 | private const DEFAULT_HOST = 'localhost'; 20 | private const DEFAULT_PORT = 5672; 21 | private const DEFAULT_VHOST = '/'; 22 | private const DEFAULT_USER = 'guest'; 23 | private const DEFAULT_PASS = 'guest'; 24 | 25 | /** 26 | * @var string 27 | */ 28 | public $host; 29 | 30 | /** 31 | * @var int 32 | */ 33 | public $port; 34 | 35 | /** 36 | * @var string 37 | */ 38 | public $user; 39 | 40 | /** 41 | * @var string 42 | */ 43 | public $pass; 44 | 45 | /** 46 | * @var string 47 | */ 48 | public $vhost; 49 | 50 | /** 51 | * Connection timeout (in milliseconds) 52 | * 53 | * @var int 54 | */ 55 | public $timeout = 1000; 56 | 57 | /** 58 | * Heartbeat interval (in milliseconds) 59 | * 60 | * @var int 61 | */ 62 | public $heartbeat = 60000; 63 | 64 | /** 65 | * @var int 66 | */ 67 | public $qosSize = 0; 68 | 69 | /** 70 | * @var int 71 | */ 72 | public $qosCount = 0; 73 | 74 | /** 75 | * @var bool 76 | */ 77 | public $qosGlobal = false; 78 | 79 | /** 80 | * @var bool 81 | */ 82 | public $tcpNoDelay = false; 83 | 84 | /** 85 | * @var int 86 | */ 87 | public $tcpAttempts = 2; 88 | 89 | /** 90 | * @var int 91 | */ 92 | public $maxChannel = 0xFFFF; 93 | 94 | /** 95 | * @var int 96 | */ 97 | public $maxFrame = 0xFFFF; 98 | 99 | public function __construct( 100 | string $host = self::DEFAULT_HOST, 101 | int $port = self::DEFAULT_PORT, 102 | string $user = self::DEFAULT_USER, 103 | string $pass = self::DEFAULT_PASS, 104 | string $vhost = null 105 | ) { 106 | $this->host = $host; 107 | $this->port = $port; 108 | $this->user = $user; 109 | $this->pass = $pass; 110 | $this->vhost = $vhost ?: self::DEFAULT_VHOST; 111 | } 112 | 113 | /** 114 | * @throws \PHPinnacle\Ridge\Exception\ConfigurationException 115 | */ 116 | public static function parse(string $dsn): self 117 | { 118 | if ($dsn === '') { 119 | throw ConfigurationException::emptyDSN(); 120 | } 121 | 122 | $parts = \parse_url($dsn); 123 | 124 | if ($parts === false) { 125 | throw ConfigurationException::incorrectDSN($dsn); 126 | } 127 | 128 | \parse_str($parts['query'] ?? '', $options); 129 | 130 | if (isset($parts['path']) && $parts['path'] !== '') { 131 | /** @var string|false $vhost */ 132 | $vhost = \substr($parts['path'], 1); 133 | 134 | if ($vhost !== false) { 135 | $parts['path'] = $vhost; 136 | } 137 | } 138 | 139 | $self = new self( 140 | $parts['host'] ?? self::DEFAULT_HOST, 141 | $parts['port'] ?? self::DEFAULT_PORT, 142 | $parts['user'] ?? self::DEFAULT_USER, 143 | $parts['pass'] ?? self::DEFAULT_PASS, 144 | $parts['path'] ?? self::DEFAULT_VHOST, 145 | ); 146 | 147 | if (isset($options['timeout'])) { 148 | $self->timeout = (int)$options['timeout']; 149 | } 150 | 151 | if (isset($options['heartbeat'])) { 152 | $self->heartbeat = (int)$options['heartbeat']; 153 | } 154 | 155 | if (isset($options['max_frame'])) { 156 | $self->maxFrame = (int)$options['max_frame']; 157 | } 158 | 159 | if (isset($options['max_channel'])) { 160 | $self->maxChannel = (int)$options['max_channel']; 161 | } 162 | 163 | if (isset($options['qos_size'])) { 164 | $self->qosSize = (int)$options['qos_size']; 165 | } 166 | 167 | if (isset($options['qos_count'])) { 168 | $self->qosCount = (int)$options['qos_count']; 169 | } 170 | 171 | if (isset($options['qos_global'])) { 172 | $self->qosGlobal = (bool)$options['qos_global']; 173 | } 174 | 175 | if (isset($options['tcp_nodelay'])) { 176 | $self->tcpNoDelay = (bool)$options['tcp_nodelay']; 177 | } 178 | 179 | if (isset($options['tcp_attempts'])) { 180 | $self->tcpAttempts = (int)$options['tcp_attempts']; 181 | } 182 | 183 | return $self; 184 | } 185 | 186 | public function uri(): string 187 | { 188 | return \sprintf('tcp://%s:%d', $this->host, $this->port); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/Connection.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use Evenement\EventEmitterTrait; 16 | use PHPinnacle\Ridge\Exception\ConnectionException; 17 | use function Amp\asyncCall, Amp\call, Amp\Socket\connect; 18 | use Amp\Socket\ConnectContext; 19 | use Amp\Loop; 20 | use Amp\Promise; 21 | use Amp\Socket\Socket; 22 | use PHPinnacle\Ridge\Protocol\AbstractFrame; 23 | 24 | final class Connection 25 | { 26 | use EventEmitterTrait; 27 | 28 | public const EVENT_CLOSE = 'close'; 29 | 30 | /** 31 | * @var string 32 | */ 33 | private $uri; 34 | 35 | /** 36 | * @var Parser 37 | */ 38 | private $parser; 39 | 40 | /** 41 | * @var Socket|null 42 | */ 43 | private $socket; 44 | 45 | private bool $socketClosedExpectedly = false; 46 | 47 | /** 48 | * @var callable[][][] 49 | * @psalm-var array, array>> 50 | */ 51 | private $callbacks = []; 52 | 53 | /** 54 | * @var int 55 | */ 56 | private $lastWrite = 0; 57 | 58 | /** 59 | * @var int 60 | */ 61 | private $lastRead = 0; 62 | 63 | /** 64 | * @var string|null 65 | */ 66 | private $heartbeatWatcherId; 67 | 68 | public function __construct(string $uri) 69 | { 70 | $this->uri = $uri; 71 | $this->parser = new Parser; 72 | } 73 | 74 | public function connected(): bool 75 | { 76 | return $this->socket !== null && $this->socket->isClosed() === false; 77 | } 78 | 79 | /** 80 | * @throws \PHPinnacle\Ridge\Exception\ConnectionException 81 | */ 82 | public function write(Buffer $payload): Promise 83 | { 84 | $this->lastWrite = Loop::now(); 85 | 86 | if ($this->socket !== null) { 87 | try { 88 | return $this->socket->write($payload->flush()); 89 | } catch (\Throwable $throwable) { 90 | throw ConnectionException::writeFailed($throwable); 91 | } 92 | } 93 | 94 | throw ConnectionException::socketClosed(); 95 | } 96 | 97 | /** 98 | * @throws \PHPinnacle\Ridge\Exception\ConnectionException 99 | */ 100 | public function method(int $channel, Buffer $payload): Promise 101 | { 102 | return $this->write((new Buffer) 103 | ->appendUint8(1) 104 | ->appendUint16($channel) 105 | ->appendUint32($payload->size()) 106 | ->append($payload) 107 | ->appendUint8(206) 108 | ); 109 | } 110 | 111 | /** 112 | * @psalm-param class-string $frame 113 | */ 114 | public function subscribe(int $channel, string $frame, callable $callback): void 115 | { 116 | $this->callbacks[$channel][$frame][] = $callback; 117 | } 118 | 119 | public function cancel(int $channel): void 120 | { 121 | unset($this->callbacks[$channel]); 122 | } 123 | 124 | /** 125 | * @throws \PHPinnacle\Ridge\Exception\ConnectionException 126 | */ 127 | public function open(int $timeout, int $maxAttempts, bool $noDelay): Promise 128 | { 129 | return call( 130 | function () use ($timeout, $maxAttempts, $noDelay) { 131 | $context = new ConnectContext(); 132 | 133 | if ($maxAttempts > 0) { 134 | $context = $context->withMaxAttempts($maxAttempts); 135 | } 136 | 137 | if ($timeout > 0) { 138 | $context = $context->withConnectTimeout($timeout); 139 | } 140 | 141 | if ($noDelay) { 142 | $context = $context->withTcpNoDelay(); 143 | } 144 | 145 | $this->socket = yield connect($this->uri, $context); 146 | $this->socketClosedExpectedly = false; 147 | $this->lastRead = Loop::now(); 148 | 149 | asyncCall( 150 | function () { 151 | if ($this->socket === null) { 152 | throw ConnectionException::socketClosed(); 153 | } 154 | 155 | while (null !== $chunk = yield $this->socket->read()) { 156 | $this->parser->append($chunk); 157 | 158 | while ($frame = $this->parser->parse()) { 159 | $class = \get_class($frame); 160 | $this->lastRead = Loop::now(); 161 | 162 | /** 163 | * @psalm-suppress PossiblyInvalidArgument 164 | * 165 | * @var callable(AbstractFrame):Promise $callback 166 | */ 167 | foreach ($this->callbacks[(int)$frame->channel][$class] ?? [] as $i => $callback) { 168 | /** @phpstan-ignore-next-line */ 169 | if (yield call($callback, $frame)) { 170 | unset($this->callbacks[(int)$frame->channel][$class][$i]); 171 | } 172 | } 173 | } 174 | } 175 | 176 | $this->emit(self::EVENT_CLOSE, $this->socketClosedExpectedly ? [] : [Exception\ConnectionException::lostConnection()]); 177 | $this->socket = null; 178 | } 179 | ); 180 | } 181 | ); 182 | } 183 | 184 | public function heartbeat(int $timeout): void 185 | { 186 | /** 187 | * Heartbeat interval should be timeout / 2 according to rabbitmq docs 188 | * @link https://www.rabbitmq.com/heartbeats.html#heartbeats-timeout 189 | * 190 | * We run the callback even more often to avoid race conditions if the loop is a bit under pressure 191 | * otherwise we could miss heartbeats in rare conditions 192 | */ 193 | $interval = (int) ($timeout / 2); 194 | $this->heartbeatWatcherId = Loop::repeat( 195 | (int) ($interval / 3), 196 | function (string $watcherId) use ($interval, $timeout){ 197 | $currentTime = Loop::now(); 198 | 199 | if (null !== $this->socket) { 200 | $lastWrite = $this->lastWrite ?: $currentTime; 201 | 202 | $nextHeartbeat = $lastWrite + $interval; 203 | 204 | if ($currentTime >= $nextHeartbeat) { 205 | yield $this->write((new Buffer) 206 | ->appendUint8(8) 207 | ->appendUint16(0) 208 | ->appendUint32(0) 209 | ->appendUint8(206) 210 | ); 211 | } 212 | 213 | unset($lastWrite, $nextHeartbeat); 214 | } 215 | 216 | if ( 217 | 0 !== $this->lastRead && 218 | $currentTime > ($this->lastRead + $timeout + 1000) 219 | ) 220 | { 221 | Loop::cancel($watcherId); 222 | } 223 | 224 | unset($currentTime); 225 | }); 226 | } 227 | 228 | public function close(): void 229 | { 230 | $this->callbacks = []; 231 | 232 | if ($this->heartbeatWatcherId !== null) { 233 | Loop::cancel($this->heartbeatWatcherId); 234 | 235 | $this->heartbeatWatcherId = null; 236 | } 237 | 238 | if ($this->socket !== null) { 239 | $this->socketClosedExpectedly = true; 240 | $this->socket->close(); 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /src/Constants.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | final class Constants 16 | { 17 | public const CONNECTION_CHANNEL = 0; 18 | 19 | public const FRAME_METHOD = 1; 20 | public const FRAME_HEADER = 2; 21 | public const FRAME_BODY = 3; 22 | public const FRAME_HEARTBEAT = 8; 23 | public const FRAME_MIN_SIZE = 4096; 24 | public const FRAME_END = 0xCE; 25 | 26 | public const STATUS_REPLY_SUCCESS = 200; 27 | public const STATUS_CONTENT_TOO_LARGE = 311; 28 | public const STATUS_NO_ROUTE = 312; 29 | public const STATUS_NO_CONSUMERS = 313; 30 | public const STATUS_CONNECTION_FORCED = 320; 31 | public const STATUS_INVALID_PATH = 402; 32 | public const STATUS_ACCESS_REFUSED = 403; 33 | public const STATUS_NOT_FOUND = 404; 34 | public const STATUS_RESOURCE_LOCKED = 405; 35 | public const STATUS_PRECONDITION_FAILED = 406; 36 | public const STATUS_FRAME_ERROR = 501; 37 | public const STATUS_SYNTAX_ERROR = 502; 38 | public const STATUS_COMMAND_INVALID = 503; 39 | public const STATUS_CHANNEL_ERROR = 504; 40 | public const STATUS_UNEXPECTED_FRAME = 505; 41 | public const STATUS_RESOURCE_ERROR = 506; 42 | public const STATUS_NOT_ALLOWED = 530; 43 | public const STATUS_NOT_IMPLEMENTED = 540; 44 | public const STATUS_INTERNAL_ERROR = 541; 45 | 46 | public const CLASS_CONNECTION = 10; 47 | public const CLASS_CHANNEL = 20; 48 | public const CLASS_ACCESS = 30; 49 | public const CLASS_EXCHANGE = 40; 50 | public const CLASS_QUEUE = 50; 51 | public const CLASS_BASIC = 60; 52 | public const CLASS_TX = 90; 53 | public const CLASS_CONFIRM = 85; 54 | 55 | public const METHOD_CONNECTION_START = 10; 56 | public const METHOD_CONNECTION_START_OK = 11; 57 | public const METHOD_CONNECTION_SECURE = 20; 58 | public const METHOD_CONNECTION_SECURE_OK = 21; 59 | public const METHOD_CONNECTION_TUNE = 30; 60 | public const METHOD_CONNECTION_TUNE_OK = 31; 61 | public const METHOD_CONNECTION_OPEN = 40; 62 | public const METHOD_CONNECTION_OPEN_OK = 41; 63 | public const METHOD_CONNECTION_CLOSE = 50; 64 | public const METHOD_CONNECTION_CLOSE_OK = 51; 65 | public const METHOD_CONNECTION_BLOCKED = 60; 66 | public const METHOD_CONNECTION_UNBLOCKED = 61; 67 | 68 | public const METHOD_CHANNEL_OPEN = 10; 69 | public const METHOD_CHANNEL_OPEN_OK = 11; 70 | public const METHOD_CHANNEL_FLOW = 20; 71 | public const METHOD_CHANNEL_FLOW_OK = 21; 72 | public const METHOD_CHANNEL_CLOSE = 40; 73 | public const METHOD_CHANNEL_CLOSE_OK = 41; 74 | 75 | public const METHOD_ACCESS_REQUEST = 10; 76 | public const METHOD_ACCESS_REQUEST_OK = 11; 77 | 78 | public const METHOD_EXCHANGE_DECLARE = 10; 79 | public const METHOD_EXCHANGE_DECLARE_OK = 11; 80 | public const METHOD_EXCHANGE_DELETE = 20; 81 | public const METHOD_EXCHANGE_DELETE_OK = 21; 82 | public const METHOD_EXCHANGE_BIND = 30; 83 | public const METHOD_EXCHANGE_BIND_OK = 31; 84 | public const METHOD_EXCHANGE_UNBIND = 40; 85 | public const METHOD_EXCHANGE_UNBIND_OK = 51; 86 | 87 | public const METHOD_QUEUE_DECLARE = 10; 88 | public const METHOD_QUEUE_DECLARE_OK = 11; 89 | public const METHOD_QUEUE_BIND = 20; 90 | public const METHOD_QUEUE_BIND_OK = 21; 91 | public const METHOD_QUEUE_PURGE = 30; 92 | public const METHOD_QUEUE_PURGE_OK = 31; 93 | public const METHOD_QUEUE_DELETE = 40; 94 | public const METHOD_QUEUE_DELETE_OK = 41; 95 | public const METHOD_QUEUE_UNBIND = 50; 96 | public const METHOD_QUEUE_UNBIND_OK = 51; 97 | 98 | public const METHOD_BASIC_QOS = 10; 99 | public const METHOD_BASIC_QOS_OK = 11; 100 | public const METHOD_BASIC_CONSUME = 20; 101 | public const METHOD_BASIC_CONSUME_OK = 21; 102 | public const METHOD_BASIC_CANCEL = 30; 103 | public const METHOD_BASIC_CANCEL_OK = 31; 104 | public const METHOD_BASIC_PUBLISH = 40; 105 | public const METHOD_BASIC_RETURN = 50; 106 | public const METHOD_BASIC_DELIVER = 60; 107 | public const METHOD_BASIC_GET = 70; 108 | public const METHOD_BASIC_GET_OK = 71; 109 | public const METHOD_BASIC_GET_EMPTY = 72; 110 | public const METHOD_BASIC_ACK = 80; 111 | public const METHOD_BASIC_REJECT = 90; 112 | public const METHOD_BASIC_RECOVER_ASYNC = 100; 113 | public const METHOD_BASIC_RECOVER = 110; 114 | public const METHOD_BASIC_RECOVER_OK = 111; 115 | public const METHOD_BASIC_NACK = 120; 116 | 117 | public const METHOD_TX_SELECT = 10; 118 | public const METHOD_TX_SELECT_OK = 11; 119 | public const METHOD_TX_COMMIT = 20; 120 | public const METHOD_TX_COMMIT_OK = 21; 121 | public const METHOD_TX_ROLLBACK = 30; 122 | public const METHOD_TX_ROLLBACK_OK = 31; 123 | 124 | public const METHOD_CONFIRM_SELECT = 10; 125 | public const METHOD_CONFIRM_SELECT_OK = 11; 126 | 127 | public const FIELD_BOOLEAN = 0x74; // 't' 128 | public const FIELD_SHORT_SHORT_INT = 0x62; // 'b' 129 | public const FIELD_SHORT_SHORT_UINT = 0x42; // 'B' 130 | public const FIELD_SHORT_INT = 0x55; // 'U' 131 | public const FIELD_SHORT_UINT = 0x75; // 'u' 132 | public const FIELD_LONG_INT = 0x49; // 'I' 133 | public const FIELD_LONG_UINT = 0x69; // 'i' 134 | public const FIELD_LONG_LONG_INT = 0x4C; // 'L' 135 | public const FIELD_LONG_LONG_UINT = 0x6C; // 'l' 136 | public const FIELD_FLOAT = 0x66; // 'f' 137 | public const FIELD_DOUBLE = 0x64; // 'd' 138 | public const FIELD_DECIMAL = 0x44; // 'D' 139 | public const FIELD_SHORT_STRING = 0x73; // 's' 140 | public const FIELD_LONG_STRING = 0x53; // 'S' 141 | public const FIELD_ARRAY = 0x41; // 'A' 142 | public const FIELD_TIMESTAMP = 0x54; // 'T' 143 | public const FIELD_TABLE = 0x46; // 'F' 144 | public const FIELD_NULL = 0x56; // 'V' 145 | } 146 | -------------------------------------------------------------------------------- /src/Consumer.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use function Amp\asyncCall; 16 | 17 | final class Consumer 18 | { 19 | /** 20 | * @var Channel 21 | */ 22 | private $channel; 23 | 24 | /** 25 | * @var MessageReceiver 26 | */ 27 | private $receiver; 28 | 29 | /** 30 | * @var callable[] 31 | * @psalm-var array 32 | */ 33 | private $listeners = []; 34 | 35 | public function __construct(Channel $channel, MessageReceiver $receiver) 36 | { 37 | $this->channel = $channel; 38 | $this->receiver = $receiver; 39 | } 40 | 41 | public function start(): void 42 | { 43 | $this->receiver->onMessage( 44 | function (Message $message) { 45 | if (!$tag = $message->consumerTag) { 46 | return; 47 | } 48 | 49 | if (!isset($this->listeners[$tag])) { 50 | return; 51 | } 52 | 53 | /** @psalm-suppress MixedArgumentTypeCoercion */ 54 | asyncCall($this->listeners[$tag], $message, $this->channel); 55 | } 56 | ); 57 | } 58 | 59 | public function stop(): void 60 | { 61 | $this->listeners = []; 62 | } 63 | 64 | public function subscribe(string $tag, callable $listener): void 65 | { 66 | $this->listeners[$tag] = $listener; 67 | } 68 | 69 | public function cancel(string $tag): void 70 | { 71 | unset($this->listeners[$tag]); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Events.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use function Amp\asyncCall; 16 | 17 | final class Events 18 | { 19 | /** 20 | * @var Channel 21 | */ 22 | private $channel; 23 | 24 | /** 25 | * @var MessageReceiver 26 | */ 27 | private $receiver; 28 | 29 | public function __construct(Channel $channel, MessageReceiver $receiver) 30 | { 31 | $this->channel = $channel; 32 | $this->receiver = $receiver; 33 | } 34 | 35 | public function onAck(callable $listener): self 36 | { 37 | $this->onFrame(Protocol\BasicAckFrame::class, $listener); 38 | 39 | return $this; 40 | } 41 | 42 | public function onNack(callable $listener): self 43 | { 44 | $this->onFrame(Protocol\BasicNackFrame::class, $listener); 45 | 46 | return $this; 47 | } 48 | 49 | public function onReturn(callable $listener): self 50 | { 51 | $this->receiver->onMessage( 52 | function (Message $message) use ($listener) { 53 | if (!$message->returned) { 54 | return; 55 | } 56 | 57 | /** @psalm-suppress MixedArgumentTypeCoercion */ 58 | asyncCall($listener, $message, $this->channel); 59 | } 60 | ); 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * @psalm-param class-string $frame 67 | */ 68 | private function onFrame(string $frame, callable $callback): void 69 | { 70 | $this->receiver->onFrame( 71 | $frame, 72 | function (Protocol\AcknowledgmentFrame $frame) use ($callback) { 73 | /** @psalm-suppress MixedArgumentTypeCoercion */ 74 | asyncCall($callback, $frame->deliveryTag, $frame->multiple, $this->channel); 75 | } 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Exception/ChannelException.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types = 1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | final class ChannelException extends RidgeException 16 | { 17 | public static function notReady(int $id): self 18 | { 19 | return new self(\sprintf('Trying to open not ready channel #%d.', $id)); 20 | } 21 | 22 | public static function alreadyClosed(int $id): self 23 | { 24 | return new self(\sprintf('Trying to close already closed channel #%d.', $id)); 25 | } 26 | 27 | public static function notOpen(int $id): self 28 | { 29 | return new self(\sprintf('Trying to write to a closed channel #%d.', $id)); 30 | } 31 | 32 | public static function notRegularFor(string $mode): self 33 | { 34 | return new self(\sprintf('Channel not in regular mode, cannot change to %s mode.', $mode)); 35 | } 36 | 37 | public static function notTransactional(): self 38 | { 39 | return new self('Channel not in transactional mode.'); 40 | } 41 | 42 | public static function getInProgress(): self 43 | { 44 | return new self( 45 | 'Another `basic.get` already in progress. You should use `basic.consume` instead of multiple `basic.get`.' 46 | ); 47 | } 48 | 49 | public static function frameOrder(): self 50 | { 51 | return new self('Consume frames order malformed.'); 52 | } 53 | 54 | public static function bodyOverflow(int $remaining): self 55 | { 56 | return new self(\sprintf('Body overflow, received %d more bytes.', $remaining)); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Exception/ClassInvalid.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | final class ClassInvalid extends ProtocolException 16 | { 17 | public function __construct(int $classId) 18 | { 19 | parent::__construct(\sprintf('Unhandled method frame class `%d`.', $classId)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Exception/ClientException.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | use PHPinnacle\Ridge\Protocol; 16 | 17 | final class ClientException extends RidgeException 18 | { 19 | public static function unexpectedResponse(\Throwable $error): self 20 | { 21 | return new self('Unexpected response.', (int)$error->getCode(), $error); 22 | } 23 | 24 | public static function notConnected(): self 25 | { 26 | return new self('Client is not connected to server.'); 27 | } 28 | 29 | public static function disconnected(): self { 30 | return new self('The client was unexpectedly disconnected from the server'); 31 | } 32 | 33 | public static function alreadyConnected(): self 34 | { 35 | return new self('Client is already connected/connecting.'); 36 | } 37 | 38 | public static function notSupported(string $available): self 39 | { 40 | return new self(\sprintf('Server does not support AMQPLAIN mechanism (supported: %s).', $available)); 41 | } 42 | 43 | public static function noChannelsAvailable(): self 44 | { 45 | return new self('No available channels.'); 46 | } 47 | 48 | public static function connectionClosed(Protocol\ConnectionCloseFrame $frame): self 49 | { 50 | return new self(\sprintf('Connection closed by server: %s.', $frame->replyText), $frame->replyCode); 51 | } 52 | 53 | public static function unknownFrameClass(Protocol\AbstractFrame $frame): self 54 | { 55 | return new self(\sprintf('Unhandled frame `%s`.', \get_class($frame))); 56 | } 57 | 58 | public static function unknownMethodFrame(Protocol\AbstractFrame $frame): self 59 | { 60 | return new self(\sprintf('Unhandled method frame `%s`.', \get_class($frame))); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Exception/ConfigurationException.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | /** 16 | * 17 | */ 18 | final class ConfigurationException extends RidgeException 19 | { 20 | public static function emptyDSN(): self 21 | { 22 | return new self('Connection DSN can\'t be empty'); 23 | } 24 | 25 | public static function incorrectDSN(string $dsn): self 26 | { 27 | return new self(\sprintf('Can\'t parse specified connection DSN (%s)', $dsn)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Exception/ConnectionException.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | /** 16 | * 17 | */ 18 | final class ConnectionException extends RidgeException 19 | { 20 | public static function writeFailed(\Throwable $previous): self 21 | { 22 | return new self( 23 | \sprintf('Error writing to socket: %s', $previous->getMessage()), 24 | (int)$previous->getCode(), 25 | $previous 26 | ); 27 | } 28 | 29 | public static function socketClosed(): self 30 | { 31 | return new self('Attempting to write to a closed socket'); 32 | } 33 | 34 | public static function lostConnection(): self 35 | { 36 | return new self('Socket was closed unexpectedly'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Exception/MethodInvalid.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | final class MethodInvalid extends ProtocolException 16 | { 17 | public function __construct(int $classId, int $methodId) 18 | { 19 | parent::__construct(\sprintf('Unhandled method frame method `%d` in class `%d`.', $methodId, $classId)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Exception/ProtocolException.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | use PHPinnacle\Ridge\Constants; 16 | use PHPinnacle\Ridge\Protocol\AbstractFrame; 17 | 18 | class ProtocolException extends RidgeException 19 | { 20 | public static function invalidFrameEnd(int $frameEnd): self 21 | { 22 | return new self( 23 | \sprintf( 24 | 'Frame end byte invalid - expected 0x%02x, got 0x%02x.', 25 | Constants::FRAME_END, 26 | $frameEnd 27 | ) 28 | ); 29 | } 30 | 31 | public static function unknownFrameType(int $type): self 32 | { 33 | return new self(\sprintf('Unhandled frame type `%d`.', $type)); 34 | } 35 | 36 | public static function unknownFrameClass(AbstractFrame $frame): self 37 | { 38 | return new self(\sprintf('Unhandled frame `%s`', \get_class($frame))); 39 | } 40 | 41 | public static function notEmptyHeartbeat(): self 42 | { 43 | return new self('Heartbeat frame must be empty.'); 44 | } 45 | 46 | public static function unknownFieldType(int $fieldType): self 47 | { 48 | $cType = \ctype_print(\chr($fieldType)) ? ' (`' . \chr($fieldType) . '`)' : ''; 49 | 50 | return new self(\sprintf('Unhandled field type 0x%02x%s.', $fieldType, $cType)); 51 | } 52 | 53 | public static function unknownValueType(mixed $value): self 54 | { 55 | $class = (\is_object($value) ? ' (class `' . \get_class($value) . '`)' : ''); 56 | 57 | return new self(\sprintf('Unhandled value type `%s`%s.', \gettype($value), $class)); 58 | } 59 | 60 | public static function unsupportedDeliveryTag(): self 61 | { 62 | return new self('Delivery tag can\'t be null'); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Exception/RidgeException.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Exception; 14 | 15 | abstract class RidgeException extends \RuntimeException 16 | { 17 | } 18 | -------------------------------------------------------------------------------- /src/Message.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | final class Message 16 | { 17 | /** 18 | * @psalm-readonly 19 | * 20 | * @var string 21 | */ 22 | public $content; 23 | 24 | /** 25 | * @psalm-readonly 26 | * 27 | * @var string 28 | */ 29 | public $exchange; 30 | 31 | /** 32 | * @psalm-readonly 33 | * 34 | * @var string 35 | */ 36 | public $routingKey; 37 | 38 | /** 39 | * @psalm-readonly 40 | * 41 | * @var string|null 42 | */ 43 | public $consumerTag; 44 | 45 | /** 46 | * @psalm-readonly 47 | * 48 | * @var int|null 49 | */ 50 | public $deliveryTag; 51 | 52 | /** 53 | * @psalm-readonly 54 | * 55 | * @var bool 56 | */ 57 | public $redelivered; 58 | 59 | /** 60 | * @psalm-readonly 61 | * 62 | * @var bool 63 | */ 64 | public $returned; 65 | 66 | /** 67 | * @psalm-readonly 68 | * 69 | * @var array 70 | */ 71 | public $headers; 72 | 73 | public function __construct( 74 | string $content, 75 | string $exchange, 76 | string $routingKey, 77 | ?string $consumerTag = null, 78 | ?int $deliveryTag = null, 79 | bool $redelivered = false, 80 | bool $returned = false, 81 | array $headers = [] 82 | ) { 83 | $this->content = $content; 84 | $this->exchange = $exchange; 85 | $this->routingKey = $routingKey; 86 | $this->consumerTag = $consumerTag; 87 | $this->deliveryTag = $deliveryTag; 88 | $this->redelivered = $redelivered; 89 | $this->returned = $returned; 90 | $this->headers = $headers; 91 | } 92 | 93 | public function header(string $name, mixed $default = null): mixed 94 | { 95 | return $this->headers[$name] ?? $default; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/MessageReceiver.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | use function Amp\asyncCall; 16 | 17 | final class MessageReceiver 18 | { 19 | public const 20 | STATE_WAIT = 0, 21 | STATE_HEAD = 1, 22 | STATE_BODY = 2; 23 | 24 | /** 25 | * @var Channel 26 | */ 27 | private $channel; 28 | 29 | /** 30 | * @var Connection 31 | */ 32 | private $connection; 33 | 34 | /** 35 | * @var Buffer 36 | */ 37 | private $buffer; 38 | 39 | /** 40 | * @var int 41 | */ 42 | private $state = self::STATE_WAIT; 43 | 44 | /** 45 | * @var int 46 | */ 47 | private $remaining = 0; 48 | 49 | /** 50 | * @var callable[] 51 | */ 52 | private $callbacks = []; 53 | 54 | /** 55 | * @var Protocol\BasicDeliverFrame|null 56 | */ 57 | private $deliver; 58 | 59 | /** 60 | * @var Protocol\BasicReturnFrame|null 61 | */ 62 | private $return; 63 | 64 | /** 65 | * @var Protocol\ContentHeaderFrame|null 66 | */ 67 | private $header; 68 | 69 | public function __construct(Channel $channel, Connection $connection) 70 | { 71 | $this->channel = $channel; 72 | $this->connection = $connection; 73 | $this->buffer = new Buffer; 74 | } 75 | 76 | public function start(): void 77 | { 78 | $this->onFrame(Protocol\BasicReturnFrame::class, [$this, 'receiveReturn']); 79 | $this->onFrame(Protocol\BasicDeliverFrame::class, [$this, 'receiveDeliver']); 80 | $this->onFrame(Protocol\ContentHeaderFrame::class, [$this, 'receiveHeader']); 81 | $this->onFrame(Protocol\ContentBodyFrame::class, [$this, 'receiveBody']); 82 | } 83 | 84 | public function stop(): void 85 | { 86 | $this->callbacks = []; 87 | } 88 | 89 | public function onMessage(callable $callback): void 90 | { 91 | $this->callbacks[] = $callback; 92 | } 93 | 94 | /** 95 | * @psalm-param class-string $frame 96 | */ 97 | public function onFrame(string $frame, callable $callback): void 98 | { 99 | $this->connection->subscribe($this->channel->id(), $frame, $callback); 100 | } 101 | 102 | public function receiveReturn(Protocol\BasicReturnFrame $frame): void 103 | { 104 | if ($this->state !== self::STATE_WAIT) { 105 | return; 106 | } 107 | 108 | $this->return = $frame; 109 | $this->state = self::STATE_HEAD; 110 | } 111 | 112 | public function receiveDeliver(Protocol\BasicDeliverFrame $frame): void 113 | { 114 | if ($this->state !== self::STATE_WAIT) { 115 | return; 116 | } 117 | 118 | $this->deliver = $frame; 119 | $this->state = self::STATE_HEAD; 120 | } 121 | 122 | public function receiveHeader(Protocol\ContentHeaderFrame $frame): void 123 | { 124 | if ($this->state !== self::STATE_HEAD) { 125 | return; 126 | } 127 | 128 | $this->state = self::STATE_BODY; 129 | $this->header = $frame; 130 | $this->remaining = $frame->bodySize; 131 | 132 | $this->runCallbacks(); 133 | } 134 | 135 | public function receiveBody(Protocol\ContentBodyFrame $frame): void 136 | { 137 | if ($this->state !== self::STATE_BODY) { 138 | return; 139 | } 140 | 141 | $this->buffer->append((string)$frame->payload); 142 | 143 | $this->remaining -= (int)$frame->size; 144 | 145 | if ($this->remaining < 0) { 146 | throw Exception\ChannelException::bodyOverflow($this->remaining); 147 | } 148 | 149 | $this->runCallbacks(); 150 | } 151 | 152 | /** 153 | * @throws \PHPinnacle\Ridge\Exception\ChannelException 154 | */ 155 | private function runCallbacks(): void 156 | { 157 | if ($this->remaining !== 0) { 158 | return; 159 | } 160 | 161 | if ($this->return) { 162 | $message = new Message( 163 | $this->buffer->flush(), 164 | $this->return->exchange, 165 | $this->return->routingKey, 166 | null, 167 | null, 168 | false, 169 | true, 170 | $this->header !== null ? $this->header->toArray() : [] 171 | ); 172 | } else { 173 | if ($this->deliver) { 174 | $message = new Message( 175 | $this->buffer->flush(), 176 | $this->deliver->exchange, 177 | $this->deliver->routingKey, 178 | $this->deliver->consumerTag, 179 | $this->deliver->deliveryTag, 180 | $this->deliver->redelivered, 181 | false, 182 | $this->header !== null ? $this->header->toArray() : [] 183 | ); 184 | } else { 185 | throw Exception\ChannelException::frameOrder(); 186 | } 187 | } 188 | 189 | $this->return = null; 190 | $this->deliver = null; 191 | $this->header = null; 192 | 193 | foreach ($this->callbacks as $callback) { 194 | /** @psalm-suppress MixedArgumentTypeCoercion */ 195 | asyncCall($callback, $message); 196 | } 197 | 198 | $this->state = self::STATE_WAIT; 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/Parser.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge; 12 | 13 | final class Parser 14 | { 15 | /** 16 | * @var Buffer 17 | */ 18 | private $buffer; 19 | 20 | public function __construct() 21 | { 22 | $this->buffer = new Buffer; 23 | } 24 | 25 | public function append(string $chunk): void 26 | { 27 | $this->buffer->append($chunk); 28 | } 29 | 30 | /** 31 | * Consumes AMQP frame from buffer. 32 | * 33 | * Returns NULL if there are not enough data to construct whole frame. 34 | * 35 | * @throws \PHPinnacle\Buffer\BufferOverflow 36 | * @throws \PHPinnacle\Ridge\Exception\ProtocolException 37 | */ 38 | public function parse(): ?Protocol\AbstractFrame 39 | { 40 | if ($this->buffer->size() < 7) { 41 | return null; 42 | } 43 | 44 | $size = $this->buffer->readUint32(3); 45 | $length = $size + 8; 46 | 47 | if ($this->buffer->size() < $length) { 48 | return null; 49 | } 50 | 51 | $type = $this->buffer->readUint8(); 52 | $channel = $this->buffer->readUint16(1); 53 | $payload = $this->buffer->read($size, 7); 54 | $frameEnd = $this->buffer->readUint8($length - 1); 55 | 56 | $this->buffer->discard($length); 57 | 58 | if ($frameEnd !== Constants::FRAME_END) { 59 | throw Exception\ProtocolException::invalidFrameEnd($frameEnd); 60 | } 61 | 62 | switch ($type) { 63 | case Constants::FRAME_HEADER: 64 | $frame = Protocol\ContentHeaderFrame::unpack(new Buffer($payload)); 65 | 66 | break; 67 | case Constants::FRAME_BODY: 68 | $frame = new Protocol\ContentBodyFrame; 69 | $frame->payload = $payload; 70 | 71 | break; 72 | case Constants::FRAME_METHOD: 73 | $frame = $this->consumeMethodFrame(new Buffer($payload)); 74 | 75 | break; 76 | case Constants::FRAME_HEARTBEAT: 77 | $frame = new Protocol\HeartbeatFrame; 78 | 79 | break; 80 | default: 81 | throw Exception\ProtocolException::unknownFrameType($type); 82 | } 83 | 84 | /** @var Protocol\AbstractFrame $frame */ 85 | $frame->type = $type; 86 | $frame->size = $size; 87 | $frame->channel = $channel; 88 | 89 | return $frame; 90 | } 91 | 92 | /** 93 | * Consumes AMQP method frame. 94 | * 95 | * @throws \PHPinnacle\Buffer\BufferOverflow 96 | * @throws \PHPinnacle\Ridge\Exception\ClassInvalid 97 | */ 98 | private function consumeMethodFrame(Buffer $buffer): Protocol\MethodFrame 99 | { 100 | $classId = $buffer->consumeUint16(); 101 | $methodId = $buffer->consumeUint16(); 102 | 103 | return match ($classId) { 104 | Constants::CLASS_BASIC => $this->consumeBasicFrame($methodId, $buffer), 105 | Constants::CLASS_CONNECTION => $this->consumeConnectionFrame($methodId, $buffer), 106 | Constants::CLASS_CHANNEL => $this->consumeChannelFrame($methodId, $buffer), 107 | Constants::CLASS_EXCHANGE => $this->consumeExchangeFrame($methodId, $buffer), 108 | Constants::CLASS_QUEUE => $this->consumeQueueFrame($methodId, $buffer), 109 | Constants::CLASS_TX => $this->consumeTxFrame($methodId), 110 | Constants::CLASS_CONFIRM => $this->consumeConfirmFrame($methodId, $buffer), 111 | default => throw new Exception\ClassInvalid($classId), 112 | }; 113 | } 114 | 115 | /** 116 | * @return Protocol\MethodFrame 117 | * 118 | * @throws \PHPinnacle\Ridge\Exception\MethodInvalid 119 | * @throws \PHPinnacle\Buffer\BufferOverflow 120 | */ 121 | private function consumeBasicFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame 122 | { 123 | return match ($methodId) { 124 | Constants::METHOD_BASIC_DELIVER => Protocol\BasicDeliverFrame::unpack($buffer), 125 | Constants::METHOD_BASIC_GET => Protocol\BasicGetFrame::unpack($buffer), 126 | Constants::METHOD_BASIC_GET_OK => Protocol\BasicGetOkFrame::unpack($buffer), 127 | Constants::METHOD_BASIC_GET_EMPTY => Protocol\BasicGetEmptyFrame::unpack($buffer), 128 | Constants::METHOD_BASIC_PUBLISH => Protocol\BasicPublishFrame::unpack($buffer), 129 | Constants::METHOD_BASIC_RETURN => Protocol\BasicReturnFrame::unpack($buffer), 130 | Constants::METHOD_BASIC_ACK => Protocol\BasicAckFrame::unpack($buffer), 131 | Constants::METHOD_BASIC_NACK => Protocol\BasicNackFrame::unpack($buffer), 132 | Constants::METHOD_BASIC_REJECT => Protocol\BasicRejectFrame::unpack($buffer), 133 | Constants::METHOD_BASIC_QOS => Protocol\BasicQosFrame::unpack($buffer), 134 | Constants::METHOD_BASIC_QOS_OK => new Protocol\BasicQosOkFrame, 135 | Constants::METHOD_BASIC_CONSUME => Protocol\BasicConsumeFrame::unpack($buffer), 136 | Constants::METHOD_BASIC_CONSUME_OK => Protocol\BasicConsumeOkFrame::unpack($buffer), 137 | Constants::METHOD_BASIC_CANCEL => Protocol\BasicCancelFrame::unpack($buffer), 138 | Constants::METHOD_BASIC_CANCEL_OK => Protocol\BasicCancelOkFrame::unpack($buffer), 139 | Constants::METHOD_BASIC_RECOVER => Protocol\BasicRecoverFrame::unpack($buffer), 140 | Constants::METHOD_BASIC_RECOVER_OK => new Protocol\BasicRecoverOkFrame, 141 | Constants::METHOD_BASIC_RECOVER_ASYNC => Protocol\BasicRecoverAsyncFrame::unpack($buffer), 142 | default => throw new Exception\MethodInvalid(Constants::CLASS_BASIC, $methodId), 143 | }; 144 | } 145 | 146 | /** 147 | * @return Protocol\MethodFrame 148 | * 149 | * @throws \PHPinnacle\Ridge\Exception\MethodInvalid 150 | * @throws \PHPinnacle\Buffer\BufferOverflow 151 | */ 152 | private function consumeConnectionFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame 153 | { 154 | return match ($methodId) { 155 | Constants::METHOD_CONNECTION_START => Protocol\ConnectionStartFrame::unpack($buffer), 156 | Constants::METHOD_CONNECTION_START_OK => Protocol\ConnectionStartOkFrame::unpack($buffer), 157 | Constants::METHOD_CONNECTION_SECURE => Protocol\ConnectionSecureFrame::unpack($buffer), 158 | Constants::METHOD_CONNECTION_SECURE_OK => Protocol\ConnectionSecureOkFrame::unpack($buffer), 159 | Constants::METHOD_CONNECTION_TUNE => Protocol\ConnectionTuneFrame::unpack($buffer), 160 | Constants::METHOD_CONNECTION_TUNE_OK => Protocol\ConnectionTuneOkFrame::unpack($buffer), 161 | Constants::METHOD_CONNECTION_OPEN => Protocol\ConnectionOpenFrame::unpack($buffer), 162 | Constants::METHOD_CONNECTION_OPEN_OK => Protocol\ConnectionOpenOkFrame::unpack($buffer), 163 | Constants::METHOD_CONNECTION_CLOSE => Protocol\ConnectionCloseFrame::unpack($buffer), 164 | Constants::METHOD_CONNECTION_CLOSE_OK => new Protocol\ConnectionCloseOkFrame, 165 | Constants::METHOD_CONNECTION_BLOCKED => Protocol\ConnectionBlockedFrame::unpack($buffer), 166 | Constants::METHOD_CONNECTION_UNBLOCKED => new Protocol\ConnectionUnblockedFrame, 167 | default => throw new Exception\MethodInvalid(Constants::CLASS_CONNECTION, $methodId), 168 | }; 169 | } 170 | 171 | /** 172 | * @return Protocol\MethodFrame 173 | * 174 | * @throws \PHPinnacle\Ridge\Exception\MethodInvalid 175 | * @throws \PHPinnacle\Buffer\BufferOverflow 176 | */ 177 | private function consumeChannelFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame 178 | { 179 | return match ($methodId) { 180 | Constants::METHOD_CHANNEL_OPEN => Protocol\ChannelOpenFrame::unpack($buffer), 181 | Constants::METHOD_CHANNEL_OPEN_OK => Protocol\ChannelOpenOkFrame::unpack($buffer), 182 | Constants::METHOD_CHANNEL_FLOW => Protocol\ChannelFlowFrame::unpack($buffer), 183 | Constants::METHOD_CHANNEL_FLOW_OK => Protocol\ChannelFlowOkFrame::unpack($buffer), 184 | Constants::METHOD_CHANNEL_CLOSE => Protocol\ChannelCloseFrame::unpack($buffer), 185 | Constants::METHOD_CHANNEL_CLOSE_OK => new Protocol\ChannelCloseOkFrame, 186 | default => throw new Exception\MethodInvalid(Constants::CLASS_CHANNEL, $methodId), 187 | }; 188 | } 189 | 190 | /** 191 | * @return Protocol\MethodFrame 192 | * 193 | * @throws \PHPinnacle\Ridge\Exception\MethodInvalid 194 | * @throws \PHPinnacle\Buffer\BufferOverflow 195 | */ 196 | private function consumeExchangeFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame 197 | { 198 | return match ($methodId) { 199 | Constants::METHOD_EXCHANGE_DECLARE => Protocol\ExchangeDeclareFrame::unpack($buffer), 200 | Constants::METHOD_EXCHANGE_DECLARE_OK => new Protocol\ExchangeDeclareOkFrame, 201 | Constants::METHOD_EXCHANGE_DELETE => Protocol\ExchangeDeleteFrame::unpack($buffer), 202 | Constants::METHOD_EXCHANGE_DELETE_OK => new Protocol\ExchangeDeleteOkFrame, 203 | Constants::METHOD_EXCHANGE_BIND => Protocol\ExchangeBindFrame::unpack($buffer), 204 | Constants::METHOD_EXCHANGE_BIND_OK => new Protocol\ExchangeBindOkFrame, 205 | Constants::METHOD_EXCHANGE_UNBIND => Protocol\ExchangeUnbindFrame::unpack($buffer), 206 | Constants::METHOD_EXCHANGE_UNBIND_OK => new Protocol\ExchangeUnbindOkFrame, 207 | default => throw new Exception\MethodInvalid(Constants::CLASS_EXCHANGE, $methodId), 208 | }; 209 | } 210 | 211 | /** 212 | * @return Protocol\MethodFrame 213 | * 214 | * @throws \PHPinnacle\Ridge\Exception\MethodInvalid 215 | * @throws \PHPinnacle\Buffer\BufferOverflow 216 | */ 217 | private function consumeQueueFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame 218 | { 219 | return match ($methodId) { 220 | Constants::METHOD_QUEUE_DECLARE => Protocol\QueueDeclareFrame::unpack($buffer), 221 | Constants::METHOD_QUEUE_DECLARE_OK => Protocol\QueueDeclareOkFrame::unpack($buffer), 222 | Constants::METHOD_QUEUE_BIND => Protocol\QueueBindFrame::unpack($buffer), 223 | Constants::METHOD_QUEUE_BIND_OK => new Protocol\QueueBindOkFrame, 224 | Constants::METHOD_QUEUE_UNBIND => Protocol\QueueUnbindFrame::unpack($buffer), 225 | Constants::METHOD_QUEUE_UNBIND_OK => new Protocol\QueueUnbindOkFrame, 226 | Constants::METHOD_QUEUE_PURGE => Protocol\QueuePurgeFrame::unpack($buffer), 227 | Constants::METHOD_QUEUE_PURGE_OK => Protocol\QueuePurgeOkFrame::unpack($buffer), 228 | Constants::METHOD_QUEUE_DELETE => Protocol\QueueDeleteFrame::unpack($buffer), 229 | Constants::METHOD_QUEUE_DELETE_OK => Protocol\QueueDeleteOkFrame::unpack($buffer), 230 | default => throw new Exception\MethodInvalid(Constants::CLASS_QUEUE, $methodId), 231 | }; 232 | } 233 | 234 | /** 235 | * @throws \PHPinnacle\Ridge\Exception\MethodInvalid 236 | */ 237 | private function consumeTxFrame(int $methodId): Protocol\MethodFrame 238 | { 239 | return match ($methodId) { 240 | Constants::METHOD_TX_SELECT => new Protocol\TxSelectFrame, 241 | Constants::METHOD_TX_SELECT_OK => new Protocol\TxSelectOkFrame, 242 | Constants::METHOD_TX_COMMIT => new Protocol\TxCommitFrame, 243 | Constants::METHOD_TX_COMMIT_OK => new Protocol\TxCommitOkFrame, 244 | Constants::METHOD_TX_ROLLBACK => new Protocol\TxRollbackFrame, 245 | Constants::METHOD_TX_ROLLBACK_OK => new Protocol\TxRollbackOkFrame, 246 | default => throw new Exception\MethodInvalid(Constants::CLASS_TX, $methodId), 247 | }; 248 | } 249 | 250 | /** 251 | * @throws \PHPinnacle\Ridge\Exception\MethodInvalid 252 | * @throws \PHPinnacle\Buffer\BufferOverflow 253 | */ 254 | private function consumeConfirmFrame(int $methodId, Buffer $buffer): Protocol\MethodFrame 255 | { 256 | return match ($methodId) { 257 | Constants::METHOD_CONFIRM_SELECT => Protocol\ConfirmSelectFrame::unpack($buffer), 258 | Constants::METHOD_CONFIRM_SELECT_OK => new Protocol\ConfirmSelectOkFrame, 259 | default => throw new Exception\MethodInvalid(Constants::CLASS_CONFIRM, $methodId), 260 | }; 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /src/Properties.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | final class Properties 16 | { 17 | public const UNKNOWN = 'unknown'; 18 | 19 | /** 20 | * @var string 21 | */ 22 | private $platform; 23 | 24 | /** 25 | * @var string 26 | */ 27 | private $product; 28 | 29 | /** 30 | * @var string 31 | */ 32 | private $version; 33 | 34 | /** 35 | * @example 36 | * publisher_confirms 37 | * exchange_exchange_bindings 38 | * basic.nack 39 | * consumer_cancel_notify 40 | * connection.blocked 41 | * consumer_priorities 42 | * authentication_failure_close 43 | * per_consumer_qos 44 | * direct_reply_to 45 | * 46 | * @var bool[] 47 | * @psalm-var array 48 | */ 49 | private $capabilities; 50 | 51 | /** 52 | * @var int 53 | */ 54 | private $maxChannel = 0xFFFF; 55 | 56 | /** 57 | * @var int 58 | */ 59 | private $maxFrame = 0xFFFF; 60 | 61 | /** 62 | * @psalm-param array $capabilities 63 | */ 64 | public function __construct(string $platform, string $product, string $version, array $capabilities) 65 | { 66 | $this->platform = $platform; 67 | $this->product = $product; 68 | $this->version = $version; 69 | $this->capabilities = $capabilities; 70 | } 71 | 72 | /** 73 | * @psalm-param array{ 74 | * platform: string|null, 75 | * product: string|null, 76 | * version: string|null, 77 | * capabilities: array|null 78 | * } $config 79 | */ 80 | public static function create(array $config): self 81 | { 82 | return new self( 83 | $config['platform'] ?? self::UNKNOWN, 84 | $config['product'] ?? self::UNKNOWN, 85 | $config['version'] ?? self::UNKNOWN, 86 | $config['capabilities'] ?? [] 87 | ); 88 | } 89 | 90 | public function tune(int $maxChannel, int $maxFrame): void 91 | { 92 | $this->maxChannel = $maxChannel; 93 | $this->maxFrame = $maxFrame; 94 | } 95 | 96 | public function capable(string $ability): bool 97 | { 98 | return $this->capabilities[$ability] ?? false; 99 | } 100 | 101 | public function platform(): string 102 | { 103 | return $this->platform; 104 | } 105 | 106 | public function product(): string 107 | { 108 | return $this->product; 109 | } 110 | 111 | public function version(): string 112 | { 113 | return $this->version; 114 | } 115 | 116 | public function maxFrame(): int 117 | { 118 | return $this->maxFrame; 119 | } 120 | 121 | public function maxChannel(): int 122 | { 123 | return $this->maxChannel; 124 | } 125 | } 126 | 127 | -------------------------------------------------------------------------------- /src/Protocol/AbstractFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Protocol; 14 | 15 | abstract class AbstractFrame 16 | { 17 | /** 18 | * @var int|null 19 | */ 20 | public $type; 21 | 22 | /** 23 | * @var int|null 24 | */ 25 | public $channel; 26 | 27 | /** 28 | * @var int|null 29 | */ 30 | public $size; 31 | 32 | /** 33 | * @var string|null 34 | */ 35 | public $payload; 36 | 37 | public function __construct(?int $type = null, ?int $channel = null, ?int $size = null, ?string $payload = null) 38 | { 39 | $this->type = $type; 40 | $this->channel = $channel; 41 | $this->size = $size; 42 | $this->payload = $payload; 43 | } 44 | } -------------------------------------------------------------------------------- /src/Protocol/AcknowledgmentFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | abstract class AcknowledgmentFrame extends MethodFrame 14 | { 15 | /** 16 | * @var int 17 | */ 18 | public $deliveryTag = 0; 19 | 20 | /** 21 | * @var bool 22 | */ 23 | public $multiple = false; 24 | } 25 | -------------------------------------------------------------------------------- /src/Protocol/BasicAckFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicAckFrame extends AcknowledgmentFrame 17 | { 18 | public function __construct() 19 | { 20 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_ACK); 21 | } 22 | 23 | /** 24 | * @throws \PHPinnacle\Buffer\BufferOverflow 25 | */ 26 | public static function unpack(Buffer $buffer): self 27 | { 28 | $self = new self; 29 | $self->deliveryTag = $buffer->consumeInt64(); 30 | [$self->multiple] = $buffer->consumeBits(1); 31 | 32 | return $self; 33 | } 34 | 35 | public function pack(): Buffer 36 | { 37 | $buffer = parent::pack(); 38 | $buffer->appendInt64($this->deliveryTag); 39 | $buffer->appendBits([$this->multiple]); 40 | 41 | return $buffer; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Protocol/BasicCancelFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicCancelFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $consumerTag; 22 | 23 | /** 24 | * @var bool 25 | */ 26 | public $nowait = false; 27 | 28 | public function __construct() 29 | { 30 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CANCEL); 31 | } 32 | 33 | /** 34 | * @throws \PHPinnacle\Buffer\BufferOverflow 35 | */ 36 | public static function unpack(Buffer $buffer): self 37 | { 38 | $self = new self; 39 | $self->consumerTag = $buffer->consumeString(); 40 | [$self->nowait] = $buffer->consumeBits(1); 41 | 42 | return $self; 43 | } 44 | 45 | public function pack(): Buffer 46 | { 47 | $buffer = parent::pack(); 48 | $buffer->appendString($this->consumerTag); 49 | $buffer->appendBits([$this->nowait]); 50 | 51 | return $buffer; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Protocol/BasicCancelOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicCancelOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $consumerTag; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CANCEL_OK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->consumerTag = $buffer->consumeString(); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendString($this->consumerTag); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/BasicConsumeFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicConsumeFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $queue = ''; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $consumerTag = ''; 32 | 33 | /** 34 | * @var bool 35 | */ 36 | public $noLocal = false; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $noAck = false; 42 | 43 | /** 44 | * @var bool 45 | */ 46 | public $exclusive = false; 47 | 48 | /** 49 | * @var bool 50 | */ 51 | public $nowait = false; 52 | 53 | /** 54 | * @var array 55 | */ 56 | public $arguments = []; 57 | 58 | public function __construct() 59 | { 60 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CONSUME); 61 | } 62 | 63 | /** 64 | * @throws \PHPinnacle\Buffer\BufferOverflow 65 | */ 66 | public static function unpack(Buffer $buffer): self 67 | { 68 | $self = new self; 69 | $self->reserved1 = $buffer->consumeInt16(); 70 | $self->queue = $buffer->consumeString(); 71 | $self->consumerTag = $buffer->consumeString(); 72 | 73 | [$self->noLocal, $self->noAck, $self->exclusive, $self->nowait] = $buffer->consumeBits(4); 74 | 75 | $self->arguments = $buffer->consumeTable(); 76 | 77 | return $self; 78 | } 79 | 80 | public function pack(): Buffer 81 | { 82 | $buffer = parent::pack(); 83 | $buffer->appendInt16($this->reserved1); 84 | $buffer->appendString($this->queue); 85 | $buffer->appendString($this->consumerTag); 86 | $buffer->appendBits([$this->noLocal, $this->noAck, $this->exclusive, $this->nowait]); 87 | $buffer->appendTable($this->arguments); 88 | 89 | return $buffer; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Protocol/BasicConsumeOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicConsumeOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $consumerTag; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_CONSUME_OK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->consumerTag = $buffer->consumeString(); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendString($this->consumerTag); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/BasicDeliverFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicDeliverFrame extends MessageFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $consumerTag; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_DELIVER); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->consumerTag = $buffer->consumeString(); 35 | $self->deliveryTag = $buffer->consumeInt64(); 36 | [$self->redelivered] = $buffer->consumeBits(1); 37 | $self->exchange = $buffer->consumeString(); 38 | $self->routingKey = $buffer->consumeString(); 39 | 40 | return $self; 41 | } 42 | 43 | public function pack(): Buffer 44 | { 45 | $buffer = parent::pack(); 46 | $buffer->appendString($this->consumerTag); 47 | $buffer->appendInt64($this->deliveryTag); 48 | $buffer->appendBits([$this->redelivered]); 49 | $buffer->appendString($this->exchange); 50 | $buffer->appendString($this->routingKey); 51 | 52 | return $buffer; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Protocol/BasicGetEmptyFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicGetEmptyFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $clusterId = ''; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_GET_EMPTY); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->clusterId = $buffer->consumeString(); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendString($this->clusterId); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/BasicGetFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicGetFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $queue = ''; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | public $noAck = false; 32 | 33 | public function __construct() 34 | { 35 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_GET); 36 | } 37 | 38 | /** 39 | * @throws \PHPinnacle\Buffer\BufferOverflow 40 | */ 41 | public static function unpack(Buffer $buffer): self 42 | { 43 | $self = new self; 44 | $self->reserved1 = $buffer->consumeInt16(); 45 | $self->queue = $buffer->consumeString(); 46 | [$self->noAck] = $buffer->consumeBits(1); 47 | 48 | return $self; 49 | } 50 | 51 | public function pack(): Buffer 52 | { 53 | $buffer = parent::pack(); 54 | $buffer->appendInt16($this->reserved1); 55 | $buffer->appendString($this->queue); 56 | $buffer->appendBits([$this->noAck]); 57 | 58 | return $buffer; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Protocol/BasicGetOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicGetOkFrame extends MessageFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $messageCount; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_GET_OK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->deliveryTag = $buffer->consumeInt64(); 35 | [$self->redelivered] = $buffer->consumeBits(1); 36 | $self->exchange = $buffer->consumeString(); 37 | $self->routingKey = $buffer->consumeString(); 38 | $self->messageCount = $buffer->consumeInt32(); 39 | 40 | return $self; 41 | } 42 | 43 | public function pack(): Buffer 44 | { 45 | $buffer = parent::pack(); 46 | $buffer->appendInt64($this->deliveryTag); 47 | $buffer->appendBits([$this->redelivered]); 48 | $buffer->appendString($this->exchange); 49 | $buffer->appendString($this->routingKey); 50 | $buffer->appendInt32($this->messageCount); 51 | 52 | return $buffer; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Protocol/BasicNackFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicNackFrame extends AcknowledgmentFrame 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $requeue = true; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_NACK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->deliveryTag = $buffer->consumeInt64(); 35 | 36 | [$self->multiple, $self->requeue] = $buffer->consumeBits(2); 37 | 38 | return $self; 39 | } 40 | 41 | public function pack(): Buffer 42 | { 43 | $buffer = parent::pack(); 44 | $buffer->appendInt64($this->deliveryTag); 45 | $buffer->appendBits([$this->multiple, $this->requeue]); 46 | 47 | return $buffer; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Protocol/BasicPublishFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicPublishFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $exchange = ''; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $routingKey = ''; 32 | 33 | /** 34 | * @var bool 35 | */ 36 | public $mandatory = false; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $immediate = false; 42 | 43 | public function __construct() 44 | { 45 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_PUBLISH); 46 | } 47 | 48 | /** 49 | * @throws \PHPinnacle\Buffer\BufferOverflow 50 | */ 51 | public static function unpack(Buffer $buffer): self 52 | { 53 | $self = new self; 54 | $self->reserved1 = $buffer->consumeInt16(); 55 | $self->exchange = $buffer->consumeString(); 56 | $self->routingKey = $buffer->consumeString(); 57 | 58 | [$self->mandatory, $self->immediate] = $buffer->consumeBits(2); 59 | 60 | return $self; 61 | } 62 | 63 | public function pack(): Buffer 64 | { 65 | $buffer = parent::pack(); 66 | $buffer->appendInt16($this->reserved1); 67 | $buffer->appendString($this->exchange); 68 | $buffer->appendString($this->routingKey); 69 | $buffer->appendBits([$this->mandatory, $this->immediate]); 70 | 71 | return $buffer; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Protocol/BasicQosFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicQosFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $prefetchSize = 0; 22 | 23 | /** 24 | * @var int 25 | */ 26 | public $prefetchCount = 0; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | public $global = false; 32 | 33 | public function __construct() 34 | { 35 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_QOS); 36 | } 37 | 38 | /** 39 | * @throws \PHPinnacle\Buffer\BufferOverflow 40 | */ 41 | public static function unpack(Buffer $buffer): self 42 | { 43 | $self = new self; 44 | $self->prefetchSize = $buffer->consumeInt32(); 45 | $self->prefetchCount = $buffer->consumeInt16(); 46 | [$self->global] = $buffer->consumeBits(1); 47 | 48 | return $self; 49 | } 50 | 51 | public function pack(): Buffer 52 | { 53 | $buffer = parent::pack(); 54 | $buffer->appendInt32($this->prefetchSize); 55 | $buffer->appendInt16($this->prefetchCount); 56 | $buffer->appendBits([$this->global]); 57 | 58 | return $buffer; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Protocol/BasicQosOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class BasicQosOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_QOS_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/BasicRecoverAsyncFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicRecoverAsyncFrame extends MethodFrame 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $requeue = false; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_RECOVER_ASYNC); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | [$self->requeue] = $buffer->consumeBits(1); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendBits([$this->requeue]); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/BasicRecoverFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicRecoverFrame extends MethodFrame 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $requeue = false; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_RECOVER); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | [$self->requeue] = $buffer->consumeBits(1); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendBits([$this->requeue]); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/BasicRecoverOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class BasicRecoverOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_RECOVER_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/BasicRejectFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicRejectFrame extends AcknowledgmentFrame 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $requeue = true; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_REJECT); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->deliveryTag = $buffer->consumeInt64(); 35 | [$self->requeue] = $buffer->consumeBits(1); 36 | 37 | return $self; 38 | } 39 | 40 | public function pack(): Buffer 41 | { 42 | $buffer = parent::pack(); 43 | $buffer->appendInt64($this->deliveryTag); 44 | $buffer->appendBits([$this->requeue]); 45 | 46 | return $buffer; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Protocol/BasicReturnFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class BasicReturnFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $replyCode; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $replyText = ''; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $exchange; 32 | 33 | /** 34 | * @var string 35 | */ 36 | public $routingKey; 37 | 38 | public function __construct() 39 | { 40 | parent::__construct(Constants::CLASS_BASIC, Constants::METHOD_BASIC_RETURN); 41 | } 42 | 43 | /** 44 | * @throws \PHPinnacle\Buffer\BufferOverflow 45 | */ 46 | public static function unpack(Buffer $buffer): self 47 | { 48 | $self = new self; 49 | $self->replyCode = $buffer->consumeInt16(); 50 | $self->replyText = $buffer->consumeString(); 51 | $self->exchange = $buffer->consumeString(); 52 | $self->routingKey = $buffer->consumeString(); 53 | 54 | return $self; 55 | } 56 | 57 | public function pack(): Buffer 58 | { 59 | $buffer = parent::pack(); 60 | $buffer->appendInt16($this->replyCode); 61 | $buffer->appendString($this->replyText); 62 | $buffer->appendString($this->exchange); 63 | $buffer->appendString($this->routingKey); 64 | 65 | return $buffer; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Protocol/ChannelCloseFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ChannelCloseFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $replyCode; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $replyText = ''; 27 | 28 | /** 29 | * @var int 30 | */ 31 | public $closeClassId; 32 | 33 | /** 34 | * @var int 35 | */ 36 | public $closeMethodId; 37 | 38 | public function __construct() 39 | { 40 | parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_CLOSE); 41 | } 42 | 43 | /** 44 | * @throws \PHPinnacle\Buffer\BufferOverflow 45 | */ 46 | public static function unpack(Buffer $buffer): self 47 | { 48 | $self = new self; 49 | 50 | $self->replyCode = $buffer->consumeInt16(); 51 | $self->replyText = $buffer->consumeString(); 52 | $self->closeClassId = $buffer->consumeInt16(); 53 | $self->closeMethodId = $buffer->consumeInt16(); 54 | 55 | return $self; 56 | } 57 | 58 | public function pack(): Buffer 59 | { 60 | $buffer = parent::pack(); 61 | $buffer->appendInt16($this->replyCode); 62 | $buffer->appendString($this->replyText); 63 | $buffer->appendInt16($this->closeClassId); 64 | $buffer->appendInt16($this->closeMethodId); 65 | 66 | return $buffer; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Protocol/ChannelCloseOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ChannelCloseOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_CLOSE_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/ChannelFlowFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ChannelFlowFrame extends MethodFrame 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $active; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_FLOW); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | [$self->active] = $buffer->consumeBits(1); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendBits([$this->active]); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/ChannelFlowOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ChannelFlowOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $active; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_FLOW_OK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | [$self->active] = $buffer->consumeBits(1); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendBits([$this->active]); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/ChannelOpenFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ChannelOpenFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $outOfBand = ''; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_OPEN); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | 35 | $self->outOfBand = $buffer->consumeString(); 36 | 37 | return $self; 38 | } 39 | 40 | public function pack(): Buffer 41 | { 42 | $buffer = parent::pack(); 43 | $buffer->appendString($this->outOfBand); 44 | 45 | return $buffer; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Protocol/ChannelOpenOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ChannelOpenOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $channelId = ''; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CHANNEL, Constants::METHOD_CHANNEL_OPEN_OK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->channelId = $buffer->consumeText(); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendText($this->channelId); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/ConfirmSelectFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConfirmSelectFrame extends MethodFrame 17 | { 18 | /** 19 | * @var bool 20 | */ 21 | public $nowait = false; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CONFIRM, Constants::METHOD_CONFIRM_SELECT); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | [$self->nowait] = $buffer->consumeBits(1); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendBits([$this->nowait]); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/ConfirmSelectOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ConfirmSelectOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_CONFIRM, Constants::METHOD_CONFIRM_SELECT_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionBlockedFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionBlockedFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $reason = ''; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_BLOCKED); 26 | 27 | $this->channel = Constants::CONNECTION_CHANNEL; 28 | } 29 | 30 | /** 31 | * @throws \PHPinnacle\Buffer\BufferOverflow 32 | */ 33 | public static function unpack(Buffer $buffer): self 34 | { 35 | $self = new self; 36 | $self->reason = $buffer->consumeString(); 37 | 38 | return $self; 39 | } 40 | 41 | public function pack(): Buffer 42 | { 43 | $buffer = parent::pack(); 44 | $buffer->appendString($this->reason); 45 | 46 | return $buffer; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionCloseFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionCloseFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $replyCode; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $replyText = ''; 27 | 28 | /** 29 | * @var int 30 | */ 31 | public $closeClassId; 32 | 33 | /** 34 | * @var int 35 | */ 36 | public $closeMethodId; 37 | 38 | public function __construct() 39 | { 40 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_CLOSE); 41 | 42 | $this->channel = Constants::CONNECTION_CHANNEL; 43 | } 44 | 45 | /** 46 | * @throws \PHPinnacle\Buffer\BufferOverflow 47 | */ 48 | public static function unpack(Buffer $buffer): self 49 | { 50 | $self = new self; 51 | $self->replyCode = $buffer->consumeInt16(); 52 | $self->replyText = $buffer->consumeString(); 53 | $self->closeClassId = $buffer->consumeInt16(); 54 | $self->closeMethodId = $buffer->consumeInt16(); 55 | 56 | return $self; 57 | } 58 | 59 | public function pack(): Buffer 60 | { 61 | $buffer = parent::pack(); 62 | $buffer->appendInt16($this->replyCode); 63 | $buffer->appendString($this->replyText); 64 | $buffer->appendInt16($this->closeClassId); 65 | $buffer->appendInt16($this->closeMethodId); 66 | 67 | return $buffer; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionCloseOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ConnectionCloseOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_CLOSE_OK); 20 | 21 | $this->channel = Constants::CONNECTION_CHANNEL; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionOpenFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionOpenFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $virtualHost = '/'; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $capabilities = ''; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | public $insist = false; 32 | 33 | public function __construct() 34 | { 35 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_OPEN); 36 | 37 | $this->channel = Constants::CONNECTION_CHANNEL; 38 | } 39 | 40 | /** 41 | * @throws \PHPinnacle\Buffer\BufferOverflow 42 | */ 43 | public static function unpack(Buffer $buffer): self 44 | { 45 | $self = new self; 46 | $self->virtualHost = $buffer->consumeString(); 47 | $self->capabilities = $buffer->consumeString(); 48 | [$self->insist] = $buffer->consumeBits(1); 49 | 50 | return $self; 51 | } 52 | 53 | public function pack(): Buffer 54 | { 55 | $buffer = parent::pack(); 56 | $buffer->appendString($this->virtualHost); 57 | $buffer->appendString($this->capabilities); 58 | $buffer->appendBits([$this->insist]); 59 | 60 | return $buffer; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionOpenOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionOpenOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $knownHosts = ''; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_OPEN_OK); 26 | 27 | $this->channel = Constants::CONNECTION_CHANNEL; 28 | } 29 | 30 | /** 31 | * @throws \PHPinnacle\Buffer\BufferOverflow 32 | */ 33 | public static function unpack(Buffer $buffer): self 34 | { 35 | $self = new self; 36 | $self->knownHosts = $buffer->consumeString(); 37 | 38 | return $self; 39 | } 40 | 41 | public function pack(): Buffer 42 | { 43 | $buffer = parent::pack(); 44 | $buffer->appendString($this->knownHosts); 45 | 46 | return $buffer; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionSecureFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionSecureFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $challenge; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_SECURE); 26 | 27 | $this->channel = Constants::CONNECTION_CHANNEL; 28 | } 29 | 30 | /** 31 | * @throws \PHPinnacle\Buffer\BufferOverflow 32 | */ 33 | public static function unpack(Buffer $buffer): self 34 | { 35 | $self = new self; 36 | $self->challenge = $buffer->consumeText(); 37 | 38 | return $self; 39 | } 40 | 41 | public function pack(): Buffer 42 | { 43 | $buffer = parent::pack(); 44 | $buffer->appendText($this->challenge); 45 | 46 | return $buffer; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionSecureOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionSecureOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $response; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_SECURE_OK); 26 | 27 | $this->channel = Constants::CONNECTION_CHANNEL; 28 | } 29 | 30 | /** 31 | * @throws \PHPinnacle\Buffer\BufferOverflow 32 | */ 33 | public static function unpack(Buffer $buffer): self 34 | { 35 | $self = new self; 36 | $self->response = $buffer->consumeText(); 37 | 38 | return $self; 39 | } 40 | 41 | public function pack(): Buffer 42 | { 43 | $buffer = parent::pack(); 44 | $buffer->appendText($this->response); 45 | 46 | return $buffer; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionStartFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionStartFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $versionMajor = 0; 22 | 23 | /** 24 | * @var int 25 | */ 26 | public $versionMinor = 9; 27 | 28 | /** 29 | * @var array 30 | * @psalm-var array{ 31 | * platform: string, 32 | * product: string, 33 | * version: string, 34 | * capabilities: array 35 | * } 36 | */ 37 | public $serverProperties; 38 | 39 | /** 40 | * @var string 41 | */ 42 | public $mechanisms = 'PLAIN'; 43 | 44 | /** 45 | * @var string 46 | */ 47 | public $locales = 'en_US'; 48 | 49 | public function __construct() 50 | { 51 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_START); 52 | 53 | $this->channel = Constants::CONNECTION_CHANNEL; 54 | } 55 | 56 | /** 57 | * @throws \PHPinnacle\Buffer\BufferOverflow 58 | */ 59 | public static function unpack(Buffer $buffer): self 60 | { 61 | $self = new self; 62 | $self->versionMajor = $buffer->consumeUint8(); 63 | $self->versionMinor = $buffer->consumeUint8(); 64 | 65 | /** 66 | * @psalm-var array{ 67 | * platform: string, 68 | * product: string, 69 | * version: string, 70 | * capabilities: array 71 | * } $serverProperties 72 | */ 73 | $serverProperties = $buffer->consumeTable(); 74 | 75 | $self->serverProperties = $serverProperties; 76 | $self->mechanisms = $buffer->consumeText(); 77 | $self->locales = $buffer->consumeText(); 78 | 79 | return $self; 80 | } 81 | 82 | public function pack(): Buffer 83 | { 84 | $buffer = parent::pack(); 85 | $buffer->appendUint8($this->versionMajor); 86 | $buffer->appendUint8($this->versionMinor); 87 | $buffer->appendTable($this->serverProperties); 88 | $buffer->appendText($this->mechanisms); 89 | $buffer->appendText($this->locales); 90 | 91 | return $buffer; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionStartOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionStartOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var array 20 | */ 21 | public $clientProperties = []; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $mechanism = 'PLAIN'; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $response; 32 | 33 | /** 34 | * @var string 35 | */ 36 | public $locale = 'en_US'; 37 | 38 | public function __construct() 39 | { 40 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_START_OK); 41 | 42 | $this->channel = Constants::CONNECTION_CHANNEL; 43 | } 44 | 45 | /** 46 | * @throws \PHPinnacle\Buffer\BufferOverflow 47 | */ 48 | public static function unpack(Buffer $buffer): self 49 | { 50 | $self = new self; 51 | $self->clientProperties = $buffer->consumeTable(); 52 | $self->mechanism = $buffer->consumeString(); 53 | $self->response = $buffer->consumeText(); 54 | $self->locale = $buffer->consumeString(); 55 | 56 | return $self; 57 | } 58 | 59 | public function pack(): Buffer 60 | { 61 | $buffer = parent::pack(); 62 | $buffer->appendTable($this->clientProperties); 63 | $buffer->appendString($this->mechanism); 64 | $buffer->appendText($this->response); 65 | $buffer->appendString($this->locale); 66 | 67 | return $buffer; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionTuneFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionTuneFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $channelMax = 0; 22 | 23 | /** 24 | * @var int 25 | */ 26 | public $frameMax = 0; 27 | 28 | /** 29 | * @var int 30 | */ 31 | public $heartbeat = 0; 32 | 33 | public function __construct() 34 | { 35 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_TUNE); 36 | 37 | $this->channel = Constants::CONNECTION_CHANNEL; 38 | } 39 | 40 | /** 41 | * @throws \PHPinnacle\Buffer\BufferOverflow 42 | */ 43 | public static function unpack(Buffer $buffer): self 44 | { 45 | $self = new self; 46 | $self->channelMax = $buffer->consumeInt16(); 47 | $self->frameMax = $buffer->consumeInt32(); 48 | $self->heartbeat = $buffer->consumeInt16(); 49 | 50 | return $self; 51 | } 52 | 53 | public function pack(): Buffer 54 | { 55 | $buffer = parent::pack(); 56 | $buffer->appendInt16($this->channelMax); 57 | $buffer->appendInt32($this->frameMax); 58 | $buffer->appendInt16($this->heartbeat); 59 | 60 | return $buffer; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionTuneOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ConnectionTuneOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $channelMax = 0; 22 | 23 | /** 24 | * @var int 25 | */ 26 | public $frameMax = 0; 27 | 28 | /** 29 | * @var int 30 | */ 31 | public $heartbeat = 0; 32 | 33 | public function __construct() 34 | { 35 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_TUNE_OK); 36 | 37 | $this->channel = Constants::CONNECTION_CHANNEL; 38 | } 39 | 40 | /** 41 | * @throws \PHPinnacle\Buffer\BufferOverflow 42 | */ 43 | public static function unpack(Buffer $buffer): self 44 | { 45 | $self = new self; 46 | $self->channelMax = $buffer->consumeInt16(); 47 | $self->frameMax = $buffer->consumeInt32(); 48 | $self->heartbeat = $buffer->consumeInt16(); 49 | 50 | return $self; 51 | } 52 | 53 | public function pack(): Buffer 54 | { 55 | $buffer = parent::pack(); 56 | $buffer->appendInt16($this->channelMax); 57 | $buffer->appendInt32($this->frameMax); 58 | $buffer->appendInt16($this->heartbeat); 59 | 60 | return $buffer; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Protocol/ConnectionUnblockedFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ConnectionUnblockedFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_CONNECTION, Constants::METHOD_CONNECTION_UNBLOCKED); 20 | 21 | $this->channel = Constants::CONNECTION_CHANNEL; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Protocol/ContentBodyFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ContentBodyFrame extends AbstractFrame 16 | { 17 | public function __construct(?int $channel = null, ?int $payloadSize = null, ?string $payload = null) 18 | { 19 | parent::__construct(Constants::FRAME_BODY, $channel, $payloadSize, $payload); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/ContentHeaderFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ContentHeaderFrame extends AbstractFrame 17 | { 18 | private const FLAG_CONTENT_TYPE = 0x8000; 19 | private const FLAG_CONTENT_ENCODING = 0x4000; 20 | private const FLAG_HEADERS = 0x2000; 21 | private const FLAG_DELIVERY_MODE = 0x1000; 22 | private const FLAG_PRIORITY = 0x0800; 23 | private const FLAG_CORRELATION_ID = 0x0400; 24 | private const FLAG_REPLY_TO = 0x0200; 25 | private const FLAG_EXPIRATION = 0x0100; 26 | private const FLAG_MESSAGE_ID = 0x0080; 27 | private const FLAG_TIMESTAMP = 0x0040; 28 | private const FLAG_TYPE = 0x0020; 29 | private const FLAG_USER_ID = 0x0010; 30 | private const FLAG_APP_ID = 0x0008; 31 | private const FLAG_CLUSTER_ID = 0x0004; 32 | 33 | /** 34 | * @var int 35 | */ 36 | public $classId = Constants::CLASS_BASIC; 37 | 38 | /** 39 | * @var int 40 | */ 41 | public $weight = 0; 42 | 43 | /** 44 | * @var int 45 | */ 46 | public $bodySize; 47 | 48 | /** 49 | * @var int 50 | */ 51 | public $flags = 0; 52 | 53 | /** 54 | * @var string|null 55 | */ 56 | public $contentType; 57 | 58 | /** 59 | * @var string|null 60 | */ 61 | public $contentEncoding; 62 | 63 | /** 64 | * @var array 65 | */ 66 | public $headers; 67 | 68 | /** 69 | * @var int|null 70 | */ 71 | public $deliveryMode; 72 | 73 | /** 74 | * @var int|null 75 | */ 76 | public $priority; 77 | 78 | /** 79 | * @var string|null 80 | */ 81 | public $correlationId; 82 | 83 | /** 84 | * @var string|null 85 | */ 86 | public $replyTo; 87 | 88 | /** 89 | * @var string|null 90 | */ 91 | public $expiration; 92 | 93 | /** 94 | * @var string|null 95 | */ 96 | public $messageId; 97 | 98 | /** 99 | * @var \DateTimeInterface|null 100 | */ 101 | public $timestamp; 102 | 103 | /** 104 | * @var string|null 105 | */ 106 | public $typeHeader; 107 | 108 | /** 109 | * @var string|null 110 | */ 111 | public $userId; 112 | 113 | /** 114 | * @var string|null 115 | */ 116 | public $appId; 117 | 118 | /** 119 | * @var string|null 120 | */ 121 | public $clusterId; 122 | 123 | public function __construct() 124 | { 125 | parent::__construct(Constants::FRAME_HEADER); 126 | } 127 | 128 | /** 129 | * @throws \PHPinnacle\Buffer\BufferOverflow 130 | */ 131 | public static function unpack(Buffer $buffer): self 132 | { 133 | $self = new self; 134 | 135 | $self->classId = $buffer->consumeUint16(); 136 | $self->weight = $buffer->consumeUint16(); 137 | $self->bodySize = $buffer->consumeUint64(); 138 | $self->flags = $flags = $buffer->consumeUint16(); 139 | 140 | if ($flags & self::FLAG_CONTENT_TYPE) { 141 | $self->contentType = $buffer->consumeString(); 142 | } 143 | 144 | if ($flags & self::FLAG_CONTENT_ENCODING) { 145 | $self->contentEncoding = $buffer->consumeString(); 146 | } 147 | 148 | if ($flags & self::FLAG_HEADERS) { 149 | $self->headers = $buffer->consumeTable(); 150 | } 151 | 152 | if ($flags & self::FLAG_DELIVERY_MODE) { 153 | $self->deliveryMode = $buffer->consumeUint8(); 154 | } 155 | 156 | if ($flags & self::FLAG_PRIORITY) { 157 | $self->priority = $buffer->consumeUint8(); 158 | } 159 | 160 | if ($flags & self::FLAG_CORRELATION_ID) { 161 | $self->correlationId = $buffer->consumeString(); 162 | } 163 | 164 | if ($flags & self::FLAG_REPLY_TO) { 165 | $self->replyTo = $buffer->consumeString(); 166 | } 167 | 168 | if ($flags & self::FLAG_EXPIRATION) { 169 | $self->expiration = $buffer->consumeString(); 170 | } 171 | 172 | if ($flags & self::FLAG_MESSAGE_ID) { 173 | $self->messageId = $buffer->consumeString(); 174 | } 175 | 176 | if ($flags & self::FLAG_TIMESTAMP) { 177 | $self->timestamp = $buffer->consumeTimestamp(); 178 | } 179 | 180 | if ($flags & self::FLAG_TYPE) { 181 | $self->typeHeader = $buffer->consumeString(); 182 | } 183 | 184 | if ($flags & self::FLAG_USER_ID) { 185 | $self->userId = $buffer->consumeString(); 186 | } 187 | 188 | if ($flags & self::FLAG_APP_ID) { 189 | $self->appId = $buffer->consumeString(); 190 | } 191 | 192 | if ($flags & self::FLAG_CLUSTER_ID) { 193 | $self->clusterId = $buffer->consumeString(); 194 | } 195 | 196 | return $self; 197 | } 198 | 199 | public function pack(): Buffer 200 | { 201 | $buffer = new Buffer; 202 | $buffer 203 | ->appendUint16($this->classId) 204 | ->appendUint16($this->weight) 205 | ->appendUint64($this->bodySize); 206 | 207 | $flags = $this->flags; 208 | 209 | $buffer->appendUint16($flags); 210 | 211 | if ($flags & self::FLAG_CONTENT_TYPE && $this->contentType !== null) { 212 | $buffer->appendString($this->contentType); 213 | } 214 | 215 | if ($flags & self::FLAG_CONTENT_ENCODING && $this->contentEncoding !== null) { 216 | $buffer->appendString($this->contentEncoding); 217 | } 218 | 219 | if ($flags & self::FLAG_HEADERS) { 220 | $buffer->appendTable($this->headers); 221 | } 222 | 223 | if ($flags & self::FLAG_DELIVERY_MODE && $this->deliveryMode !== null) { 224 | $buffer->appendUint8($this->deliveryMode); 225 | } 226 | 227 | if ($flags & self::FLAG_PRIORITY && $this->priority) { 228 | $buffer->appendUint8($this->priority); 229 | } 230 | 231 | if ($flags & self::FLAG_CORRELATION_ID && $this->correlationId !== null) { 232 | $buffer->appendString($this->correlationId); 233 | } 234 | 235 | if ($flags & self::FLAG_REPLY_TO && $this->replyTo !== null) { 236 | $buffer->appendString($this->replyTo); 237 | } 238 | 239 | if ($flags & self::FLAG_EXPIRATION && $this->expiration !== null) { 240 | $buffer->appendString($this->expiration); 241 | } 242 | 243 | if ($flags & self::FLAG_MESSAGE_ID && $this->messageId !== null) { 244 | $buffer->appendString($this->messageId); 245 | } 246 | 247 | if ($flags & self::FLAG_TIMESTAMP && $this->timestamp !== null) { 248 | $buffer->appendTimestamp($this->timestamp); 249 | } 250 | 251 | if ($flags & self::FLAG_TYPE && $this->typeHeader !== null) { 252 | $buffer->appendString($this->typeHeader); 253 | } 254 | 255 | if ($flags & self::FLAG_USER_ID && $this->userId !== null) { 256 | $buffer->appendString($this->userId); 257 | } 258 | 259 | if ($flags & self::FLAG_APP_ID && $this->appId !== null) { 260 | $buffer->appendString($this->appId); 261 | } 262 | 263 | if ($flags & self::FLAG_CLUSTER_ID && $this->clusterId !== null) { 264 | $buffer->appendString($this->clusterId); 265 | } 266 | 267 | return $buffer; 268 | } 269 | 270 | public function toArray(): array 271 | { 272 | $headers = $this->headers ?: []; 273 | 274 | if ($this->contentType !== null) { 275 | $headers['content-type'] = $this->contentType; 276 | } 277 | 278 | if ($this->contentEncoding !== null) { 279 | $headers['content-encoding'] = $this->contentEncoding; 280 | } 281 | 282 | if ($this->deliveryMode !== null) { 283 | $headers['delivery-mode'] = $this->deliveryMode; 284 | } 285 | 286 | if ($this->priority !== null) { 287 | $headers['priority'] = $this->priority; 288 | } 289 | 290 | if ($this->correlationId !== null) { 291 | $headers['correlation-id'] = $this->correlationId; 292 | } 293 | 294 | if ($this->replyTo !== null) { 295 | $headers['reply-to'] = $this->replyTo; 296 | } 297 | 298 | if ($this->expiration !== null) { 299 | $headers['expiration'] = $this->expiration; 300 | } 301 | 302 | if ($this->messageId !== null) { 303 | $headers['message-id'] = $this->messageId; 304 | } 305 | 306 | if ($this->timestamp !== null) { 307 | $headers['timestamp'] = $this->timestamp; 308 | } 309 | 310 | if ($this->typeHeader !== null) { 311 | $headers['type'] = $this->typeHeader; 312 | } 313 | 314 | if ($this->userId !== null) { 315 | $headers['user-id'] = $this->userId; 316 | } 317 | 318 | if ($this->appId !== null) { 319 | $headers['app-id'] = $this->appId; 320 | } 321 | 322 | if ($this->clusterId !== null) { 323 | $headers['cluster-id'] = $this->clusterId; 324 | } 325 | 326 | return $headers; 327 | } 328 | } 329 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeBindFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ExchangeBindFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $destination; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $source; 32 | 33 | /** 34 | * @var string 35 | */ 36 | public $routingKey = ''; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $nowait = false; 42 | 43 | /** 44 | * @var array 45 | */ 46 | public $arguments = []; 47 | 48 | public function __construct() 49 | { 50 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_BIND); 51 | } 52 | 53 | /** 54 | * @throws \PHPinnacle\Buffer\BufferOverflow 55 | */ 56 | public static function unpack(Buffer $buffer): self 57 | { 58 | $self = new self; 59 | $self->reserved1 = $buffer->consumeInt16(); 60 | $self->destination = $buffer->consumeString(); 61 | $self->source = $buffer->consumeString(); 62 | $self->routingKey = $buffer->consumeString(); 63 | [$self->nowait] = $buffer->consumeBits(1); 64 | $self->arguments = $buffer->consumeTable(); 65 | 66 | return $self; 67 | } 68 | 69 | public function pack(): Buffer 70 | { 71 | $buffer = parent::pack(); 72 | $buffer->appendInt16($this->reserved1); 73 | $buffer->appendString($this->destination); 74 | $buffer->appendString($this->source); 75 | $buffer->appendString($this->routingKey); 76 | $buffer->appendBits([$this->nowait]); 77 | $buffer->appendTable($this->arguments); 78 | 79 | return $buffer; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeBindOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ExchangeBindOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_BIND_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeDeclareFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ExchangeDeclareFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $exchange; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $exchangeType = 'direct'; 32 | 33 | /** 34 | * @var bool 35 | */ 36 | public $passive = false; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $durable = false; 42 | 43 | /** 44 | * @var bool 45 | */ 46 | public $autoDelete = false; 47 | 48 | /** 49 | * @var bool 50 | */ 51 | public $internal = false; 52 | 53 | /** 54 | * @var bool 55 | */ 56 | public $nowait = false; 57 | 58 | /** 59 | * @var array 60 | */ 61 | public $arguments = []; 62 | 63 | public function __construct() 64 | { 65 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_DECLARE); 66 | } 67 | 68 | /** 69 | * @throws \PHPinnacle\Buffer\BufferOverflow 70 | */ 71 | public static function unpack(Buffer $buffer): self 72 | { 73 | $self = new self; 74 | $self->reserved1 = $buffer->consumeInt16(); 75 | $self->exchange = $buffer->consumeString(); 76 | $self->exchangeType = $buffer->consumeString(); 77 | 78 | [$self->passive, $self->durable, $self->autoDelete, $self->internal, $self->nowait] = $buffer->consumeBits(5); 79 | 80 | $self->arguments = $buffer->consumeTable(); 81 | 82 | return $self; 83 | } 84 | 85 | public function pack(): Buffer 86 | { 87 | $buffer = parent::pack(); 88 | $buffer->appendInt16($this->reserved1); 89 | $buffer->appendString($this->exchange); 90 | $buffer->appendString($this->exchangeType); 91 | $buffer->appendBits([$this->passive, $this->durable, $this->autoDelete, $this->internal, $this->nowait]); 92 | $buffer->appendTable($this->arguments); 93 | 94 | return $buffer; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeDeclareOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ExchangeDeclareOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_DECLARE_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeDeleteFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ExchangeDeleteFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $exchange; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | public $ifUnused = true; 32 | 33 | /** 34 | * @var bool 35 | */ 36 | public $nowait = false; 37 | 38 | public function __construct() 39 | { 40 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_DELETE); 41 | } 42 | 43 | /** 44 | * @throws \PHPinnacle\Buffer\BufferOverflow 45 | */ 46 | public static function unpack(Buffer $buffer): self 47 | { 48 | $self = new self; 49 | 50 | $self->reserved1 = $buffer->consumeInt16(); 51 | $self->exchange = $buffer->consumeString(); 52 | 53 | [$self->ifUnused, $self->nowait] = $buffer->consumeBits(2); 54 | 55 | return $self; 56 | } 57 | 58 | public function pack(): Buffer 59 | { 60 | $buffer = parent::pack(); 61 | $buffer->appendInt16($this->reserved1); 62 | $buffer->appendString($this->exchange); 63 | $buffer->appendBits([$this->ifUnused, $this->nowait]); 64 | 65 | return $buffer; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeDeleteOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ExchangeDeleteOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_DELETE_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeUnbindFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class ExchangeUnbindFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $destination; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $source; 32 | 33 | /** 34 | * @var string 35 | */ 36 | public $routingKey = ''; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $nowait = false; 42 | 43 | /** 44 | * @var array 45 | */ 46 | public $arguments = []; 47 | 48 | public function __construct() 49 | { 50 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_UNBIND); 51 | } 52 | 53 | /** 54 | * @throws \PHPinnacle\Buffer\BufferOverflow 55 | */ 56 | public static function unpack(Buffer $buffer): self 57 | { 58 | $self = new self; 59 | $self->reserved1 = $buffer->consumeInt16(); 60 | $self->destination = $buffer->consumeString(); 61 | $self->source = $buffer->consumeString(); 62 | $self->routingKey = $buffer->consumeString(); 63 | [$self->nowait] = $buffer->consumeBits(1); 64 | $self->arguments = $buffer->consumeTable(); 65 | 66 | return $self; 67 | } 68 | 69 | public function pack(): Buffer 70 | { 71 | $buffer = parent::pack(); 72 | $buffer->appendInt16($this->reserved1); 73 | $buffer->appendString($this->destination); 74 | $buffer->appendString($this->source); 75 | $buffer->appendString($this->routingKey); 76 | $buffer->appendBits([$this->nowait]); 77 | $buffer->appendTable($this->arguments); 78 | 79 | return $buffer; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Protocol/ExchangeUnbindOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class ExchangeUnbindOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_EXCHANGE, Constants::METHOD_EXCHANGE_UNBIND_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/HeartbeatFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge\Protocol; 14 | 15 | use PHPinnacle\Ridge\Constants; 16 | 17 | class HeartbeatFrame extends AbstractFrame 18 | { 19 | public function __construct() 20 | { 21 | parent::__construct(Constants::FRAME_HEARTBEAT, Constants::CONNECTION_CHANNEL, 0, ''); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Protocol/MessageFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | class MessageFrame extends MethodFrame 14 | { 15 | /** 16 | * @var string 17 | */ 18 | public $exchange; 19 | 20 | /** 21 | * @var string 22 | */ 23 | public $routingKey; 24 | 25 | /** 26 | * @var int 27 | */ 28 | public $deliveryTag; 29 | 30 | /** 31 | * @var bool 32 | */ 33 | public $redelivered = false; 34 | } 35 | -------------------------------------------------------------------------------- /src/Protocol/MethodFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class MethodFrame extends AbstractFrame 17 | { 18 | /** 19 | * @var int|null 20 | */ 21 | public $classId; 22 | 23 | /** 24 | * @var int|null 25 | */ 26 | public $methodId; 27 | 28 | public function __construct(?int $classId = null, ?int $methodId = null) 29 | { 30 | parent::__construct(Constants::FRAME_METHOD); 31 | 32 | $this->classId = $classId; 33 | $this->methodId = $methodId; 34 | } 35 | 36 | public function pack(): Buffer 37 | { 38 | $buffer = new Buffer; 39 | $buffer 40 | ->appendUint16((int)$this->classId) 41 | ->appendUint16((int)$this->methodId); 42 | 43 | return $buffer; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Protocol/QueueBindFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueueBindFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $queue = ''; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $exchange; 32 | 33 | /** 34 | * @var string 35 | */ 36 | public $routingKey = ''; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $nowait = false; 42 | 43 | /** 44 | * @var array 45 | */ 46 | public $arguments = []; 47 | 48 | public function __construct() 49 | { 50 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_BIND); 51 | } 52 | 53 | /** 54 | * @throws \PHPinnacle\Buffer\BufferOverflow 55 | */ 56 | public static function unpack(Buffer $buffer): self 57 | { 58 | $self = new self; 59 | $self->reserved1 = $buffer->consumeInt16(); 60 | $self->queue = $buffer->consumeString(); 61 | $self->exchange = $buffer->consumeString(); 62 | $self->routingKey = $buffer->consumeString(); 63 | [$self->nowait] = $buffer->consumeBits(1); 64 | $self->arguments = $buffer->consumeTable(); 65 | 66 | return $self; 67 | } 68 | 69 | public function pack(): Buffer 70 | { 71 | $buffer = parent::pack(); 72 | $buffer->appendInt16($this->reserved1); 73 | $buffer->appendString($this->queue); 74 | $buffer->appendString($this->exchange); 75 | $buffer->appendString($this->routingKey); 76 | $buffer->appendBits([$this->nowait]); 77 | $buffer->appendTable($this->arguments); 78 | 79 | return $buffer; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Protocol/QueueBindOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class QueueBindOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_BIND_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/QueueDeclareFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueueDeclareFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $queue = ''; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | public $passive = false; 32 | 33 | /** 34 | * @var bool 35 | */ 36 | public $durable = false; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $exclusive = false; 42 | 43 | /** 44 | * @var bool 45 | */ 46 | public $autoDelete = false; 47 | 48 | /** 49 | * @var bool 50 | */ 51 | public $nowait = false; 52 | 53 | /** 54 | * @var array 55 | */ 56 | public $arguments = []; 57 | 58 | public function __construct() 59 | { 60 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DECLARE); 61 | } 62 | 63 | /** 64 | * @throws \PHPinnacle\Buffer\BufferOverflow 65 | */ 66 | public static function unpack(Buffer $buffer): self 67 | { 68 | $self = new self; 69 | $self->reserved1 = $buffer->consumeInt16(); 70 | $self->queue = $buffer->consumeString(); 71 | 72 | [$self->passive, $self->durable, $self->exclusive, $self->autoDelete, $self->nowait] = $buffer->consumeBits(5); 73 | 74 | $self->arguments = $buffer->consumeTable(); 75 | 76 | return $self; 77 | } 78 | 79 | public function pack(): Buffer 80 | { 81 | $buffer = parent::pack(); 82 | $buffer->appendInt16($this->reserved1); 83 | $buffer->appendString($this->queue); 84 | $buffer->appendBits([$this->passive, $this->durable, $this->exclusive, $this->autoDelete, $this->nowait]); 85 | $buffer->appendTable($this->arguments); 86 | 87 | return $buffer; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Protocol/QueueDeclareOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueueDeclareOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var string 20 | */ 21 | public $queue; 22 | 23 | /** 24 | * @var int 25 | */ 26 | public $messageCount; 27 | 28 | /** 29 | * @var int 30 | */ 31 | public $consumerCount; 32 | 33 | public function __construct() 34 | { 35 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DECLARE_OK); 36 | } 37 | 38 | /** 39 | * @throws \PHPinnacle\Buffer\BufferOverflow 40 | */ 41 | public static function unpack(Buffer $buffer): self 42 | { 43 | $self = new self; 44 | $self->queue = $buffer->consumeString(); 45 | $self->messageCount = $buffer->consumeInt32(); 46 | $self->consumerCount = $buffer->consumeInt32(); 47 | 48 | return $self; 49 | } 50 | 51 | public function pack(): Buffer 52 | { 53 | $buffer = parent::pack(); 54 | $buffer->appendString($this->queue); 55 | $buffer->appendInt32($this->messageCount); 56 | $buffer->appendInt32($this->consumerCount); 57 | 58 | return $buffer; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Protocol/QueueDeleteFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueueDeleteFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $queue = ''; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | public $ifUnused = false; 32 | 33 | /** 34 | * @var bool 35 | */ 36 | public $ifEmpty = false; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | public $nowait = false; 42 | 43 | public function __construct() 44 | { 45 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DELETE); 46 | } 47 | 48 | /** 49 | * @throws \PHPinnacle\Buffer\BufferOverflow 50 | */ 51 | public static function unpack(Buffer $buffer): self 52 | { 53 | $self = new self; 54 | $self->reserved1 = $buffer->consumeInt16(); 55 | $self->queue = $buffer->consumeString(); 56 | 57 | [$self->ifUnused, $self->ifEmpty, $self->nowait] = $buffer->consumeBits(3); 58 | 59 | return $self; 60 | } 61 | 62 | public function pack(): Buffer 63 | { 64 | $buffer = parent::pack(); 65 | $buffer->appendInt16($this->reserved1); 66 | $buffer->appendString($this->queue); 67 | $buffer->appendBits([$this->ifUnused, $this->ifEmpty, $this->nowait]); 68 | 69 | return $buffer; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Protocol/QueueDeleteOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueueDeleteOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $messageCount; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_DELETE_OK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->messageCount = $buffer->consumeInt32(); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendInt32($this->messageCount); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/QueuePurgeFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueuePurgeFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $queue = ''; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | public $nowait = false; 32 | 33 | public function __construct() 34 | { 35 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_PURGE); 36 | } 37 | 38 | /** 39 | * @throws \PHPinnacle\Buffer\BufferOverflow 40 | */ 41 | public static function unpack(Buffer $buffer): self 42 | { 43 | $self = new self; 44 | $self->reserved1 = $buffer->consumeInt16(); 45 | $self->queue = $buffer->consumeString(); 46 | [$self->nowait] = $buffer->consumeBits(1); 47 | 48 | return $self; 49 | } 50 | 51 | public function pack(): Buffer 52 | { 53 | $buffer = parent::pack(); 54 | $buffer->appendInt16($this->reserved1); 55 | $buffer->appendString($this->queue); 56 | $buffer->appendBits([$this->nowait]); 57 | 58 | return $buffer; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Protocol/QueuePurgeOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueuePurgeOkFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $messageCount; 22 | 23 | public function __construct() 24 | { 25 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_PURGE_OK); 26 | } 27 | 28 | /** 29 | * @throws \PHPinnacle\Buffer\BufferOverflow 30 | */ 31 | public static function unpack(Buffer $buffer): self 32 | { 33 | $self = new self; 34 | $self->messageCount = $buffer->consumeInt32(); 35 | 36 | return $self; 37 | } 38 | 39 | public function pack(): Buffer 40 | { 41 | $buffer = parent::pack(); 42 | $buffer->appendInt32($this->messageCount); 43 | 44 | return $buffer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Protocol/QueueUnbindFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Buffer; 14 | use PHPinnacle\Ridge\Constants; 15 | 16 | class QueueUnbindFrame extends MethodFrame 17 | { 18 | /** 19 | * @var int 20 | */ 21 | public $reserved1 = 0; 22 | 23 | /** 24 | * @var string 25 | */ 26 | public $queue = ''; 27 | 28 | /** 29 | * @var string 30 | */ 31 | public $exchange; 32 | 33 | /** 34 | * @var string 35 | */ 36 | public $routingKey = ''; 37 | 38 | /** 39 | * @var array 40 | */ 41 | public $arguments = []; 42 | 43 | public function __construct() 44 | { 45 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_UNBIND); 46 | } 47 | 48 | /** 49 | * @throws \PHPinnacle\Buffer\BufferOverflow 50 | */ 51 | public static function unpack(Buffer $buffer): self 52 | { 53 | $self = new self; 54 | $self->reserved1 = $buffer->consumeInt16(); 55 | $self->queue = $buffer->consumeString(); 56 | $self->exchange = $buffer->consumeString(); 57 | $self->routingKey = $buffer->consumeString(); 58 | $self->arguments = $buffer->consumeTable(); 59 | 60 | return $self; 61 | } 62 | 63 | public function pack(): Buffer 64 | { 65 | $buffer = parent::pack(); 66 | $buffer->appendInt16($this->reserved1); 67 | $buffer->appendString($this->queue); 68 | $buffer->appendString($this->exchange); 69 | $buffer->appendString($this->routingKey); 70 | $buffer->appendTable($this->arguments); 71 | 72 | return $buffer; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Protocol/QueueUnbindOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class QueueUnbindOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_QUEUE, Constants::METHOD_QUEUE_UNBIND_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/TxCommitFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class TxCommitFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_TX, Constants::METHOD_TX_COMMIT); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/TxCommitOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class TxCommitOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_TX, Constants::METHOD_TX_COMMIT_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/TxRollbackFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class TxRollbackFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_TX, Constants::METHOD_TX_ROLLBACK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/TxRollbackOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class TxRollbackOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_TX, Constants::METHOD_TX_ROLLBACK_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/TxSelectFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class TxSelectFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_TX, Constants::METHOD_TX_SELECT); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Protocol/TxSelectOkFrame.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace PHPinnacle\Ridge\Protocol; 12 | 13 | use PHPinnacle\Ridge\Constants; 14 | 15 | class TxSelectOkFrame extends MethodFrame 16 | { 17 | public function __construct() 18 | { 19 | parent::__construct(Constants::CLASS_TX, Constants::METHOD_TX_SELECT_OK); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Queue.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace PHPinnacle\Ridge; 14 | 15 | final class Queue 16 | { 17 | /** 18 | * @var string 19 | */ 20 | private $name; 21 | 22 | /** 23 | * @var int 24 | */ 25 | private $messages; 26 | 27 | /** 28 | * @var int 29 | */ 30 | private $consumers; 31 | 32 | public function __construct(string $name, int $messages, int $consumers) 33 | { 34 | $this->name = $name; 35 | $this->messages = $messages; 36 | $this->consumers = $consumers; 37 | } 38 | 39 | public function name(): string 40 | { 41 | return $this->name; 42 | } 43 | 44 | public function messages(): int 45 | { 46 | return $this->messages; 47 | } 48 | 49 | public function consumers(): int 50 | { 51 | return $this->consumers; 52 | } 53 | } 54 | --------------------------------------------------------------------------------