Skip to content
This repository was archived by the owner on Oct 30, 2024. It is now read-only.

Commit e0141ff

Browse files
committed
Merge branch 'release/0.8.1'
2 parents 93e114f + 4bb9027 commit e0141ff

8 files changed

Lines changed: 149 additions & 19 deletions

File tree

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ php:
66
- 5.5
77
- 5.6
88
- 7
9+
- 7.1
910
cache:
1011
directories:
1112
- vendor

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ dist-clean:
3030
rm -f composer.phar
3131
rm -f composer.lock
3232

33+
docker-nats:
34+
docker run --rm -p 8222:8222 -p 4222:4222 -d --name nats-main nats
35+
3336
.PHONY: lint test cs cover deps dist-clean

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ A PHP client for the [NATS messaging system](https://nats.io).
1919
Requirements
2020
------------
2121

22-
* php 5.4+
22+
* php 5.5+
2323
* [nats](https://github.com/derekcollison/nats) or [gnatsd](https://github.com/apcera/gnatsd)
2424

2525

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.8.0
1+
0.8.1

src/Nats/Connection.php

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public function getSubscriptions()
115115
private $streamSocket;
116116

117117
/**
118-
* @var Generator
118+
* @var Generator|Php71RandomGenerator
119119
*/
120120
private $randomGenerator;
121121

@@ -130,8 +130,12 @@ public function __construct(ConnectionOptions $options = null)
130130
$this->pubs = 0;
131131
$this->subscriptions = [];
132132
$this->options = $options;
133-
$randomFactory = new Factory();
134-
$this->randomGenerator = $randomFactory->getLowStrengthGenerator();
133+
if(version_compare(phpversion(), '7.0', '>')){
134+
$this->randomGenerator = new Php71RandomGenerator();
135+
} else {
136+
$randomFactory = new Factory();
137+
$this->randomGenerator = $randomFactory->getLowStrengthGenerator();
138+
}
135139

136140
if (is_null($options)) {
137141
$this->options = new ConnectionOptions();
@@ -148,7 +152,21 @@ public function __construct(ConnectionOptions $options = null)
148152
private function send($payload)
149153
{
150154
$msg = $payload."\r\n";
151-
fwrite($this->streamSocket, $msg, strlen($msg));
155+
$len = strlen($msg);
156+
while (true) {
157+
if (false === ($written = @fwrite($this->streamSocket, $msg))) {
158+
throw new \Exception('Error sending data');
159+
}
160+
if ($written === 0) {
161+
throw new \Exception('Broken pipe or closed connection');
162+
}
163+
$len = $len - $written;
164+
if ($len > 0) {
165+
$msg = substr($msg, 0 - $len);
166+
} else {
167+
break;
168+
}
169+
}
152170
}
153171

154172
/**
@@ -195,16 +213,19 @@ private function getStream($address, $timeout)
195213
$errno = null;
196214
$errstr = null;
197215

216+
set_error_handler(function(){return true;});
198217
$fp = stream_socket_client($address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT);
218+
restore_error_handler();
219+
220+
if (!$fp) {
221+
throw Exception::forStreamSocketClientError($errstr, $errno);
222+
}
223+
199224
$timeout = number_format($timeout, 3);
200225
$seconds = floor($timeout);
201226
$microseconds = ($timeout - $seconds) * 1000;
202227
stream_set_timeout($fp, $seconds, $microseconds);
203228

204-
if (!$fp) {
205-
throw new \Exception($errstr, $errno);
206-
}
207-
208229
return $fp;
209230
}
210231

@@ -239,16 +260,16 @@ public function connect($timeout = null)
239260
$msg = 'CONNECT '.$this->options;
240261
$this->send($msg);
241262
$connect_response = $this->receive();
242-
if (strpos($connect_response, '-ERR')!== false) {
243-
throw new \Exception("Failing connection: $connect_response");
263+
264+
if ($this->isErrorResponse($connect_response)) {
265+
throw Exception::forFailedConnection($connect_response);
244266
}
245267

246268
$this->ping();
247269
$ping_response = $this->receive();
248-
if ($ping_response !== "PONG") {
249-
if (strpos($ping_response, '-ERR')!== false) {
250-
throw new \Exception("Failing on first ping: $ping_response");
251-
}
270+
271+
if ($this->isErrorResponse($ping_response)) {
272+
throw Exception::forFailedPing($ping_response);
252273
}
253274
}
254275

@@ -391,14 +412,14 @@ private function handleMSG($line)
391412
$msg = new Message($subject, $payload, $sid, $this);
392413

393414
if (!isset($this->subscriptions[$sid])) {
394-
throw new Exception('subscription not found');
415+
throw Exception::forSubscriptionNotFound($sid);
395416
}
396417

397418
$func = $this->subscriptions[$sid];
398419
if (is_callable($func)) {
399420
$func($msg);
400421
} else {
401-
throw new Exception('not callable');
422+
throw Exception::forSubscriptionCallbackInvalid($sid);
402423
}
403424

404425
return;
@@ -492,6 +513,9 @@ public function setChunkSize($chunkSize)
492513
*/
493514
public function close()
494515
{
516+
if ($this->streamSocket === null) {
517+
return;
518+
}
495519
fclose($this->streamSocket);
496520
$this->streamSocket = null;
497521
}
@@ -504,4 +528,15 @@ public function streamSocket()
504528
{
505529
return $this->streamSocket;
506530
}
531+
532+
/**
533+
* Indicates whether $response is an error response.
534+
*
535+
* @param string $response The Nats Server response.
536+
* @return boolean
537+
*/
538+
private function isErrorResponse($response)
539+
{
540+
return false !== strpos('-ERR', $response);
541+
}
507542
}

src/Nats/Exception.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,59 @@
66
*/
77
class Exception extends \Exception
88
{
9+
/**
10+
* Creates an Exception for a failed connection.
11+
*
12+
* @param string $response The failed error response.
13+
* @return Nats\Exception
14+
*/
15+
public static function forFailedConnection($response)
16+
{
17+
return new static(sprintf('Failed to connect: %s', $response));
18+
}
919

20+
/**
21+
* Creates an Exception for a failed PING response.
22+
*
23+
* @param string $response The failed PING response.
24+
* @return Nats\Exception
25+
*/
26+
public static function forFailedPing($response)
27+
{
28+
return new static(sprintf('Failed to ping: %s', $response));
29+
}
30+
31+
/**
32+
* Creates an Exception for an invalid Subscription Identifier (sid).
33+
*
34+
* @param string $subscription The Subscription Identifier (sid).
35+
* @return Nats\Exception
36+
*/
37+
public static function forSubscriptionNotFound($subscription)
38+
{
39+
return new static(sprintf('Subscription not found: %s', $subscription));
40+
}
41+
42+
/**
43+
* Creates an Exception for an invalid Subscription Identifier (sid) callback.
44+
*
45+
* @param string $subscription The Subscription Identifier (sid).
46+
* @return Nats\Exception
47+
*/
48+
public static function forSubscriptionCallbackInvalid($subscription)
49+
{
50+
return new static(sprintf('Subscription callback is invalid: %s', $subscription));
51+
}
52+
53+
/**
54+
* Creates an Exception for the failed creation of a Stream Socket Client.
55+
*
56+
* @param string $message The system level error message.
57+
* @param integer $code The system level error code.
58+
* @return Nats\Exception
59+
*/
60+
public static function forStreamSocketClientError($message, $code)
61+
{
62+
return new static(sprintf('A Stream Socket Client could not be created: (%d) %s', $code, $message), $code);
63+
}
1064
}

src/Nats/Php71RandomGenerator.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
4+
namespace Nats;
5+
6+
7+
8+
class Php71RandomGenerator
9+
{
10+
/**
11+
* A simple wrapper on random_bytes
12+
*
13+
* @param $len
14+
* @return string
15+
*/
16+
public function generateString($len) {
17+
return bin2hex(random_bytes($len));
18+
}
19+
}

test/ConnectionTest.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ function ($message) use ($contentLen) {
158158

159159
$i++;
160160
} while ($i < 100);
161-
162161
}
163162

164163
/**
@@ -205,4 +204,23 @@ function ($res) {
205204

206205
$this->assertTrue(true);
207206
}
207+
208+
209+
/**
210+
* Test Connecting when nats server is not available
211+
*
212+
* @return void
213+
*/
214+
public function testRefusedConnection()
215+
{
216+
$this->setExpectedException(\Exception::class);
217+
218+
$options = new ConnectionOptions();
219+
$options->setHost('localhost');
220+
$options->setPort(4223);
221+
222+
$c = new Nats\Connection($options);
223+
$c->connect();
224+
$this->assertFalse($this->c->isConnected());
225+
}
208226
}

0 commit comments

Comments
 (0)