Skip to content

Commit

Permalink
Adding persistent connection option. Always attempt to close socket w…
Browse files Browse the repository at this point in the history
…hen fwrite fails so that resource is let go
  • Loading branch information
slezakattack committed Aug 10, 2020
1 parent fe34840 commit de8fa59
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 3 deletions.
2 changes: 2 additions & 0 deletions lib/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,13 @@ protected function write($data)
$written = fwrite($this->socket, $data);
if ($written === false) {
$length = strlen($data);
fclose($this->socket);
$this->throwException("Failed to write $length bytes.");
}

if ($written < strlen($data)) {
$length = strlen($data);
fclose($this->socket);
$this->throwException("Could only write $written out of $length bytes.");
}
}
Expand Down
6 changes: 5 additions & 1 deletion lib/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Client extends Base
{
// Default options
protected static $default_options = [
'persistent' => false,
'timeout' => 5,
'fragment_size' => 4096,
'context' => null,
Expand Down Expand Up @@ -95,13 +96,16 @@ protected function connect()
$context = stream_context_create();
}

$flags = STREAM_CLIENT_CONNECT;
$flags = ($this->options['persistent'] === true) ? $flags | STREAM_CLIENT_PERSISTENT : $flags;

// Open the socket. @ is there to supress warning that we will catch in check below instead.
$this->socket = @stream_socket_client(
$host_uri . ':' . $port,
$errno,
$errstr,
$this->options['timeout'],
STREAM_CLIENT_CONNECT,
$flags,
$context
);

Expand Down
8 changes: 8 additions & 0 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,14 @@ public function testReconnect()
$this->assertTrue(MockSocket::isEmpty());
}

public function testPersistentConnection()
{
MockSocket::initialize('client.connect-persistent', $this);
$client = new Client('ws://localhost:8000/my/mock/path', ['persistent' => true]);
$client->send('Connect');
$this->assertTrue(MockSocket::isEmpty());
}

/**
* @expectedException WebSocket\BadUriException
* @expectedExceptionMessage Url should have scheme ws or wss
Expand Down
60 changes: 60 additions & 0 deletions tests/scripts/client.connect-persistent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
[
{
"function": "stream_context_create",
"params": [],
"return": "@mock-stream-context"
},
{
"function": "stream_socket_client",
"params": [
"tcp:\/\/localhost:8000",
null,
null,
5,
5,
"@mock-stream-context"
],
"return": "@mock-stream"
},
{
"function": "get_resource_type",
"params": [
"@mock-stream"
],
"return": "stream"
},
{
"function": "stream_set_timeout",
"params": [
"@mock-stream",
5
],
"return": true
},
{
"function": "fwrite",
"params": [
"@mock-stream"
],
"return-op": "key-save",
"return": 248
},
{
"function": "stream_get_line",
"params": [
"@mock-stream",
1024,
"\r\n\r\n"
],
"return-op": "key-respond",
"return": "HTTP\/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: {key}"
},
{
"function": "fwrite",
"params": [
"@mock-stream"
],
"return": 13
}
]

7 changes: 6 additions & 1 deletion tests/scripts/send-broken-write.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
],
"return": 18
},
{
"function": "fclose",
"params": [],
"return": true
},
{
"function": "stream_get_meta_data",
"params": [
Expand All @@ -28,4 +33,4 @@
"seekable": false
}
}
]
]
7 changes: 6 additions & 1 deletion tests/scripts/send-failed-write.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
],
"return": false
},
{
"function": "fclose",
"params": [],
"return": true
},
{
"function": "stream_get_meta_data",
"params": [
Expand All @@ -28,4 +33,4 @@
"seekable": false
}
}
]
]

0 comments on commit de8fa59

Please sign in to comment.