Skip to content

Commit 10abcb0

Browse files
authored
Merge pull request #573 from php-enqueue/wamp
WAMP
2 parents eb033cb + 72f35eb commit 10abcb0

36 files changed

+1498
-1
lines changed

bin/subtree-split

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ remote async-event-dispatcher [email protected]:php-enqueue/async-event-dispatcher.
6666
remote async-command [email protected]:php-enqueue/async-command.git
6767
remote mongodb [email protected]:php-enqueue/mongodb.git
6868
remote dsn [email protected]:php-enqueue/dsn.git
69+
remote wamp [email protected]:php-enqueue/wamp.git
6970

7071
split 'pkg/enqueue' enqueue
7172
split 'pkg/simple-client' simple-client
@@ -90,3 +91,4 @@ split 'pkg/async-event-dispatcher' async-event-dispatcher
9091
split 'pkg/async-command' async-command
9192
split 'pkg/mongodb' mongodb
9293
split 'pkg/dsn' dsn
94+
split 'pkg/wamp' wamp

composer.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
"php-http/guzzle6-adapter": "^1.1",
3131
"php-http/client-common": "^1.7@dev",
3232
"richardfullmer/rabbitmq-management-api": "^2.0",
33-
"predis/predis": "^1.1"
33+
"predis/predis": "^1.1",
34+
"thruway/pawl-transport": "^0.5.0",
35+
"voryx/thruway": "^0.5.3"
3436
},
3537
"require-dev": {
3638
"phpunit/phpunit": "^5.5",
@@ -75,6 +77,7 @@
7577
"Enqueue\\Stomp\\": "pkg/stomp/",
7678
"Enqueue\\Test\\": "pkg/test/",
7779
"Enqueue\\Dsn\\": "pkg/dsn/",
80+
"Enqueue\\Wamp\\": "pkg/wamp/",
7881
"Enqueue\\": "pkg/enqueue/"
7982
},
8083
"exclude-from-classmap": [

docker-compose.yml

+13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ services:
1414
- google-pubsub
1515
- rabbitmqssl
1616
- mongo
17+
- thruway
1718
- localstack
1819
volumes:
1920
- './:/mqdev'
@@ -30,6 +31,7 @@ services:
3031
- PHPREDIS_DSN=redis+phpredis://redis
3132
- GPS_DSN=gps:?projectId=mqdev&emulatorHost=http://google-pubsub:8085
3233
- SQS_DSN=sqs:?key=key&secret=secret&region=us-east-1&endpoint=http://localstack:4576&version=latest
34+
- WAMP_DSN=wamp://thruway:9090
3335
- REDIS_HOST=redis
3436
- REDIS_PORT=6379
3537
- AWS_SQS_KEY=key
@@ -104,6 +106,17 @@ services:
104106
ports:
105107
- "27017:27017"
106108

109+
thruway:
110+
image: formapro/nginx-php-fpm:latest-all-exts
111+
ports:
112+
- '9090:9090'
113+
working_dir: '/app'
114+
volumes:
115+
- './:/app'
116+
entrypoint:
117+
- '/usr/bin/php'
118+
- 'docker/thruway/WsRouter.php'
119+
107120
localstack:
108121
image: 'localstack/localstack:latest'
109122
ports:

docker/bin/test.sh

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ waitForService beanstalkd 11300 50
3737
waitForService gearmand 4730 50
3838
waitForService kafka 9092 50
3939
waitForService mongo 27017 50
40+
waitForService thruway 9090 50
4041
waitForService localstack 4576 50
4142

4243
php docker/bin/refresh-mysql-database.php

docker/thruway/WsRouter.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
require __DIR__.'/../../vendor/autoload.php';
4+
5+
use Thruway\Peer\Router;
6+
use Thruway\Transport\RatchetTransportProvider;
7+
8+
$router = new Router();
9+
10+
$transportProvider = new RatchetTransportProvider('0.0.0.0', 9090);
11+
12+
$router->addTransportProvider($transportProvider);
13+
14+
$router->start();

docs/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [Kafka](transport/kafka.md)
1111
- [Stomp](transport/stomp.md)
1212
- [Redis](transport/redis.md)
13+
- [Wamp](transport/wamp.md)
1314
- [Doctrine DBAL](transport/dbal.md)
1415
- [Filesystem](transport/filesystem.md)
1516
- [Null](transport/null.md)

docs/transport/wamp.md

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Web Application Messaging Protocol (WAMP) Transport
2+
3+
A transport for [Web Application Messaging Protocol](https://wamp-proto.org/).
4+
WAMP is an open standard WebSocket subprotocol.
5+
It uses internally Thruway PHP library [voryx/thruway](https://github.com/voryx/Thruway)
6+
7+
* [Installation](#installation)
8+
* [Start the WAMP router](#start-the-wamp-router)
9+
* [Create context](#create-context)
10+
* [Consume message](#consume-message)
11+
* [Subscription consumer](#subscription-consumer)
12+
* [Send message to topic](#send-message-to-topic)
13+
14+
## Installation
15+
16+
```bash
17+
$ composer require enqueue/wamp
18+
```
19+
20+
## Start the WAMP router
21+
22+
```bash
23+
$ php vendor/voryx/thruway/Examples/SimpleWsRouter.php
24+
```
25+
26+
Thruway is now running on 127.0.0.1 port 9090
27+
28+
29+
## Create context
30+
31+
```php
32+
<?php
33+
use Enqueue\Wamp\WampConnectionFactory;
34+
35+
$connectionFactory = new WampConnectionFactory();
36+
37+
$context = $connectionFactory->createContext();
38+
39+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
40+
$context = (new \Enqueue\ConnectionFactoryFactory())->create('wamp:')->createContext();
41+
```
42+
43+
## Consume message:
44+
45+
Start message consumer before send message to the topic
46+
47+
```php
48+
<?php
49+
/** @var \Enqueue\Wamp\WampContext $context */
50+
51+
$fooTopic = $context->createTopic('foo');
52+
53+
$consumer = $context->createConsumer($fooQueue);
54+
55+
while (true) {
56+
if ($message = $consumer->receive()) {
57+
// process a message
58+
}
59+
}
60+
```
61+
62+
## Subscription consumer
63+
64+
```php
65+
<?php
66+
use Interop\Queue\Message;
67+
use Interop\Queue\Consumer;
68+
69+
/** @var \Enqueue\Wamp\WampContext $context */
70+
/** @var \Enqueue\Wamp\WampDestination $fooQueue */
71+
/** @var \Enqueue\Wamp\WampDestination $barQueue */
72+
73+
$fooConsumer = $context->createConsumer($fooQueue);
74+
$barConsumer = $context->createConsumer($barQueue);
75+
76+
$subscriptionConsumer = $context->createSubscriptionConsumer();
77+
$subscriptionConsumer->subscribe($fooConsumer, function(Message $message, Consumer $consumer) {
78+
// process message
79+
80+
return true;
81+
});
82+
$subscriptionConsumer->subscribe($barConsumer, function(Message $message, Consumer $consumer) {
83+
// process message
84+
85+
return true;
86+
});
87+
88+
$subscriptionConsumer->consume(2000); // 2 sec
89+
```
90+
91+
## Send message to topic
92+
93+
```php
94+
<?php
95+
/** @var \Enqueue\Wamp\WampContext $context */
96+
97+
$fooTopic = $context->createTopic('foo');
98+
$message = $context->createMessage('Hello world!');
99+
100+
$context->createProducer()->send($fooTopic, $message);
101+
```
102+
103+
[back to index](../index.md)

phpunit.xml.dist

+4
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@
104104
<testsuite name="dsn">
105105
<directory>pkg/dsn/Tests</directory>
106106
</testsuite>
107+
108+
<testsuite name="wamp transport">
109+
<directory>pkg/wamp/Tests</directory>
110+
</testsuite>
107111
</testsuites>
108112

109113
<php>

pkg/enqueue/Resources.php

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Enqueue\Redis\RedisConnectionFactory;
1717
use Enqueue\Sqs\SqsConnectionFactory;
1818
use Enqueue\Stomp\StompConnectionFactory;
19+
use Enqueue\Wamp\WampConnectionFactory;
1920
use Interop\Queue\ConnectionFactory;
2021

2122
final class Resources
@@ -163,6 +164,11 @@ public static function getKnownConnections(): array
163164
'supportedSchemeExtensions' => [],
164165
'package' => 'enqueue/mongodb',
165166
];
167+
$map[WampConnectionFactory::class] = [
168+
'schemes' => ['wamp', 'ws'],
169+
'supportedSchemeExtensions' => [],
170+
'package' => 'enqueue/wamp',
171+
];
166172

167173
self::$knownConnections = $map;
168174
}

pkg/enqueue/Tests/ResourcesTest.php

+19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Enqueue\Redis\RedisConnectionFactory;
66
use Enqueue\Resources;
7+
use Enqueue\Wamp\WampConnectionFactory;
78
use Interop\Queue\ConnectionFactory;
89
use PHPUnit\Framework\TestCase;
910

@@ -127,4 +128,22 @@ public function testShouldAllowGetPreviouslyRegisteredConnection()
127128
$this->assertArrayHasKey('package', $connectionInfo);
128129
$this->assertSame('foo/bar', $connectionInfo['package']);
129130
}
131+
132+
public function testShouldHaveRegisteredWampConfiguration()
133+
{
134+
$availableConnections = Resources::getKnownConnections();
135+
136+
$this->assertInternalType('array', $availableConnections);
137+
$this->assertArrayHasKey(WampConnectionFactory::class, $availableConnections);
138+
139+
$connectionInfo = $availableConnections[WampConnectionFactory::class];
140+
$this->assertArrayHasKey('schemes', $connectionInfo);
141+
$this->assertSame(['wamp', 'ws'], $connectionInfo['schemes']);
142+
143+
$this->assertArrayHasKey('supportedSchemeExtensions', $connectionInfo);
144+
$this->assertSame([], $connectionInfo['supportedSchemeExtensions']);
145+
146+
$this->assertArrayHasKey('package', $connectionInfo);
147+
$this->assertSame('enqueue/wamp', $connectionInfo['package']);
148+
}
130149
}

pkg/test/WampExtension.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Enqueue\Test;
4+
5+
use Enqueue\Wamp\WampConnectionFactory;
6+
use Enqueue\Wamp\WampContext;
7+
8+
trait WampExtension
9+
{
10+
private function buildWampContext(): WampContext
11+
{
12+
if (false == $dsn = getenv('WAMP_DSN')) {
13+
throw new \PHPUnit_Framework_SkippedTestError('Functional tests are not allowed in this environment');
14+
}
15+
16+
return (new WampConnectionFactory($dsn))->createContext();
17+
}
18+
}

pkg/wamp/.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*~
2+
/composer.lock
3+
/composer.phar
4+
/phpunit.xml
5+
/vendor/
6+
/.idea/

pkg/wamp/.travis.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
sudo: false
2+
3+
git:
4+
depth: 10
5+
6+
language: php
7+
8+
php:
9+
- '7.1'
10+
- '7.2'
11+
12+
cache:
13+
directories:
14+
- $HOME/.composer/cache
15+
16+
install:
17+
- composer self-update
18+
- composer install
19+
20+
script:
21+
- vendor/bin/phpunit --exclude-group=functional

pkg/wamp/JsonSerializer.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Enqueue\Wamp;
6+
7+
class JsonSerializer implements Serializer
8+
{
9+
public function toString(WampMessage $message): string
10+
{
11+
$json = json_encode([
12+
'body' => $message->getBody(),
13+
'properties' => $message->getProperties(),
14+
'headers' => $message->getHeaders(),
15+
]);
16+
17+
if (JSON_ERROR_NONE !== json_last_error()) {
18+
throw new \InvalidArgumentException(sprintf(
19+
'The malformed json given. Error %s and message %s',
20+
json_last_error(),
21+
json_last_error_msg()
22+
));
23+
}
24+
25+
return $json;
26+
}
27+
28+
public function toMessage(string $string): WampMessage
29+
{
30+
$data = json_decode($string, true);
31+
if (JSON_ERROR_NONE !== json_last_error()) {
32+
throw new \InvalidArgumentException(sprintf(
33+
'The malformed json given. Error %s and message %s',
34+
json_last_error(),
35+
json_last_error_msg()
36+
));
37+
}
38+
39+
return new WampMessage($data['body'], $data['properties'], $data['headers']);
40+
}
41+
}

pkg/wamp/LICENSE

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
The MIT License (MIT)
2+
Copyright (c) 2018 Forma-Pro
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is furnished
9+
to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
THE SOFTWARE.

0 commit comments

Comments
 (0)