Skip to content

Commit

Permalink
Version 1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
sirn-se committed Dec 11, 2020
1 parent 5f8bcad commit e40a9b7
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 41 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ php:
- 7.4
- 7.3
- 7.2
- 7.1

before_script:
- make install build
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Preferred way to install is with [Composer](https://getcomposer.org/).
composer require textalk/websocket
```

* Current version support PHP versions `^7.1`.
* Current version support PHP versions `^7.2`.
* For PHP `7.1` support use version `1.4`.
* For PHP `^5.4` and `7.0` support use version `1.3`.

## Client
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
}
},
"require": {
"php": "^7.1",
"php": "^7.2",
"psr/log": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^7.0|^8.0|^9.0",
"phpunit/phpunit": "^8.0|^9.0",
"php-coveralls/php-coveralls": "^2.0",
"squizlabs/php_codesniffer": "^3.5"
}
Expand Down
2 changes: 1 addition & 1 deletion docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Convenience send methods; text(), binary(), ping(), pong() (@sirn-se)
* Optional Message instance as receive() method return (@sirn-se)
* Opcode filter for receive() method (@sirn-se)
* Fix for unordered framgemented messages (@sirn-se)
* Fix for unordered framgmented messages (@sirn-se)
* Various code re-write (@sirn-se)

## `v1.4`
Expand Down
4 changes: 2 additions & 2 deletions docs/Client.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ WebSocket\Client {
public close(int $status = 1000, mixed $message = 'ttfn') : mixed

public getName() : string|null
public getRemoteName() : string|null
public getLastOpcode(bool $frame = false) : string
public getPier() : string|null
public getLastOpcode() : string
public getCloseStatus() : int
public isConnected() : bool
public setTimeout(int $seconds) : void
Expand Down
4 changes: 2 additions & 2 deletions docs/Server.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ WebSocket\Server {
public getHeader(string $header_name) : string|null

public getName() : string|null
public getRemoteName() : string|null
public getLastOpcode(bool $frame = false) : string
public getPier() : string|null
public getLastOpcode() : string
public getCloseStatus() : int
public isConnected() : bool
public setTimeout(int $seconds) : void
Expand Down
9 changes: 7 additions & 2 deletions examples/echoserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@
}

// Setting timeout to 200 seconds to make time for all tests and manual runs.
$server = new Server($options);
try {
$server = new Server($options);
} catch (ConnectionException $e) {
echo "> ERROR: {$e->getMessage()}\n";
die();
}

echo "> Listening to port {$server->getPort()}\n";

Expand All @@ -44,7 +49,7 @@
while (true) {
$message = $server->receive();
$opcode = $server->getLastOpcode();
if ($opcode == 'close') {
if (is_null($message)) {
echo "> Closing connection\n";
continue 2;
}
Expand Down
41 changes: 23 additions & 18 deletions lib/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@

namespace WebSocket;

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Psr\Log\{LoggerAwareInterface, LoggerInterface, NullLogger};
use WebSocket\Message\Factory;

class Base implements LoggerAwareInterface
Expand All @@ -20,7 +18,6 @@ class Base implements LoggerAwareInterface
protected $options = [];
protected $is_closing = false;
protected $last_opcode = null;
protected $last_frame_opcode = null;
protected $close_status = null;
protected $logger;
private $read_buffer;
Expand All @@ -34,9 +31,9 @@ class Base implements LoggerAwareInterface
'pong' => 10,
];

public function getLastOpcode(bool $frame = false): ?string
public function getLastOpcode(): ?string
{
return $frame ? $this->last_frame_opcode : $this->last_opcode;
return $this->last_opcode;
}

public function getCloseStatus(): ?int
Expand All @@ -51,7 +48,7 @@ public function isConnected(): bool
get_resource_type($this->socket) == 'persistent stream');
}

public function setTimeout($timeout): void
public function setTimeout(int $timeout): void
{
$this->options['timeout'] = $timeout;

Expand All @@ -60,7 +57,7 @@ public function setTimeout($timeout): void
}
}

public function setFragmentSize($fragment_size): self
public function setFragmentSize(int $fragment_size): self
{
$this->options['fragment_size'] = $fragment_size;
return $this;
Expand All @@ -76,7 +73,7 @@ public function setLogger(LoggerInterface $logger = null): void
$this->logger = $logger ?: new NullLogger();
}

public function send($payload, $opcode = 'text', $masked = true): void
public function send(string $payload, string $opcode = 'text', bool $masked = true): void
{
if (!$this->isConnected()) {
$this->connect();
Expand Down Expand Up @@ -157,7 +154,7 @@ public function getName(): ?string
* Get name of remote socket, or null if not connected
* @return string|null
*/
public function getRemote(bool $pier = false): ?string
public function getPier(): ?string
{
return $this->isConnected() ? stream_socket_get_name($this->socket, true) : null;
}
Expand All @@ -175,7 +172,12 @@ public function __toString(): string
);
}

protected function sendFragment($final, $payload, $opcode, $masked): void
/**
* Receive one message.
* Will continue reading until read message match filter settings.
* Return Message instance or string according to settings.
*/
protected function sendFragment(bool $final, string $payload, string $opcode, bool $masked): void
{
$data = '';

Expand Down Expand Up @@ -233,7 +235,6 @@ public function receive()
// Continuation and factual opcode
$continuation = ($opcode == 'continuation');
$payload_opcode = $continuation ? $this->read_buffer['opcode'] : $opcode;
$this->last_frame_opcode = $payload_opcode;

// Filter frames
if (!in_array($payload_opcode, $filter)) {
Expand Down Expand Up @@ -392,7 +393,7 @@ protected function receiveFragment(): array
* @param integer $status http://tools.ietf.org/html/rfc6455#section-7.4
* @param string $message A closing message, max 125 bytes.
*/
public function close($status = 1000, $message = 'ttfn'): void
public function close(int $status = 1000, string $message = 'ttfn'): void
{
if (!$this->isConnected()) {
return;
Expand All @@ -409,7 +410,7 @@ public function close($status = 1000, $message = 'ttfn'): void
$this->receive(); // Receiving a close frame will close the socket now.
}

protected function write($data): void
protected function write(string $data): void
{
$length = strlen($data);
$written = fwrite($this->socket, $data);
Expand All @@ -422,7 +423,7 @@ protected function write($data): void
$this->logger->debug("Wrote {$written} of {$length} bytes.");
}

protected function read($length): string
protected function read(string $length): string
{
$data = '';
while (strlen($data) < $length) {
Expand All @@ -441,11 +442,15 @@ protected function read($length): string
return $data;
}

protected function throwException($message, $code = 0): void
protected function throwException(string $message, int $code = 0): void
{
$meta = $this->isConnected() ? stream_get_meta_data($this->socket) : [];
$meta = ['closed' => true];
if ($this->isConnected()) {
$meta = stream_get_meta_data($this->socket);
fclose($this->socket);
$this->socket = null;
}
$json_meta = json_encode($meta);
fclose($this->socket);
if (!empty($meta['timed_out'])) {
$this->logger->error($message, $meta);
throw new TimeoutException($message, ConnectionException::TIMED_OUT, $meta);
Expand Down
6 changes: 2 additions & 4 deletions lib/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Client extends Base
* - fragment_size: Set framgemnt size. Default: 4096
* - headers: Associative array of headers to set/override.
*/
public function __construct($uri, $options = [])
public function __construct(string $uri, array $options = [])
{
$this->options = array_merge(self::$default_options, $options);
$this->socket_uri = $uri;
Expand Down Expand Up @@ -198,11 +198,9 @@ function ($key, $value) {
*/
protected static function generateKey(): string
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"$&/()=[]{}0123456789';
$key = '';
$chars_length = strlen($chars);
for ($i = 0; $i < 16; $i++) {
$key .= $chars[mt_rand(0, $chars_length - 1)];
$key .= chr(rand(33, 126));
}
return base64_encode($key);
}
Expand Down
6 changes: 2 additions & 4 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ public function testRemoteClose(): void
$this->assertFalse($client->isConnected());
$this->assertEquals(17260, $client->getCloseStatus());
$this->assertNull($client->getLastOpcode());
$this->assertEquals('close', $client->getLastOpcode(true));
$this->assertTrue(MockSocket::isEmpty());
}

Expand Down Expand Up @@ -209,7 +208,6 @@ public function testReconnect(): void
$this->assertFalse($client->isConnected());
$this->assertEquals(1000, $client->getCloseStatus());
$this->assertNull($client->getLastOpcode());
$this->assertEquals('close', $client->getLastOpcode(true));
$this->assertTrue(MockSocket::isEmpty());

MockSocket::initialize('client.reconnect', $this);
Expand Down Expand Up @@ -413,15 +411,15 @@ public function testConvenicanceMethods(): void
MockSocket::initialize('client.connect', $this);
$client = new Client('ws://localhost:8000/my/mock/path');
$this->assertNull($client->getName());
$this->assertNull($client->getRemote());
$this->assertNull($client->getPier());
$this->assertEquals('WebSocket\Client(closed)', "{$client}");
$client->text('Connect');
MockSocket::initialize('send-convenicance', $this);
$client->binary(base64_encode('Binary content'));
$client->ping();
$client->pong();
$this->assertEquals('127.0.0.1:12345', $client->getName());
$this->assertEquals('127.0.0.1:8000', $client->getRemote());
$this->assertEquals('127.0.0.1:8000', $client->getPier());
$this->assertEquals('WebSocket\Client(127.0.0.1:12345)', "{$client}");
}
}
6 changes: 2 additions & 4 deletions tests/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ public function testServerMasked(): void
$server->close();
$this->assertFalse($server->isConnected());
$this->assertEquals(1000, $server->getCloseStatus());
$this->assertEquals('close', $server->getLastOpcode(true));
$this->assertTrue(MockSocket::isEmpty());

$server->close(); // Already closed
Expand Down Expand Up @@ -192,7 +191,6 @@ public function testRemoteClose(): void
$this->assertFalse($server->isConnected());
$this->assertEquals(17260, $server->getCloseStatus());
$this->assertNull($server->getLastOpcode());
$this->assertEquals('close', $server->getLastOpcode(true));
}

public function testSetTimeout(): void
Expand Down Expand Up @@ -411,7 +409,7 @@ public function testConvenicanceMethods(): void
MockSocket::initialize('server.construct', $this);
$server = new Server();
$this->assertNull($server->getName());
$this->assertNull($server->getRemote());
$this->assertNull($server->getPier());
$this->assertEquals('WebSocket\Server(closed)', "{$server}");
MockSocket::initialize('server.accept', $this);
$server->accept();
Expand All @@ -421,7 +419,7 @@ public function testConvenicanceMethods(): void
$server->ping();
$server->pong();
$this->assertEquals('127.0.0.1:12345', $server->getName());
$this->assertEquals('127.0.0.1:8000', $server->getRemote());
$this->assertEquals('127.0.0.1:8000', $server->getPier());
$this->assertEquals('WebSocket\Server(127.0.0.1:12345)', "{$server}");
$this->assertTrue(MockSocket::isEmpty());
}
Expand Down

0 comments on commit e40a9b7

Please sign in to comment.