Skip to content

Commit

Permalink
Add close code and reason to Listener
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Oct 5, 2024
1 parent 57cdbfb commit 06527ab
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 21 deletions.
4 changes: 3 additions & 1 deletion src/main/php/websocket/Listener.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ public abstract function message($connection, $message);
* Closes connection
*
* @param websocket.protocol.Connection $connection
* @param int $code
* @param string $reason
* @return void
*/
public function close($connection) { /* NOOP */ }
public function close($connection, $code, $reason) { /* NOOP */ }
}
14 changes: 7 additions & 7 deletions src/main/php/websocket/WebSocket.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,13 @@ public function receive($timeout= null) {
break;

case Opcodes::CLOSE:
$close= unpack('ncode/a*message', $packet);
$this->conn->close($close['code'], $close['message']);
$close= unpack('ncode/a*reason', $packet);
$this->conn->close($close['code'], $close['reason']);
$this->socket->close();

// 1000 is a normal close, all others indicate an error
if (1000 === $close['code']) return;
throw new ProtocolException('Connection closed (#'.$close['code'].'): '.$close['message']);
throw new ProtocolException('Connection closed (#'.$close['code'].'): '.$close['reason']);
}
}
}
Expand All @@ -201,18 +201,18 @@ public function receive($timeout= null) {
* Closes connection
*
* @param int $code
* @param string $message
* @param string $reason
* @return void
*/
public function close($code= 1000, $message= '') {
public function close($code= 1000, $reason= '') {
if (!$this->socket->isConnected()) return;

try {
$this->conn->message(Opcodes::CLOSE, pack('n', $code).$message, ($this->random)(4));
$this->conn->message(Opcodes::CLOSE, pack('na*', $code, $reason), ($this->random)(4));
} catch (Throwable $ignored) {
// ...
}
$this->conn->close($code, $message);
$this->conn->close($code, $reason);
$this->socket->close();
}

Expand Down
9 changes: 7 additions & 2 deletions src/main/php/websocket/protocol/Connection.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,15 @@ public function on($payload) {
/**
* Closes connection
*
* @param int $code
* @param string $reason
* @return void
*/
public function close() {
$this->listener && $this->listener->close($this);
public function close($code= 1000, $reason= '') {
if ($this->socket->isConnected()) {
$this->listener && $this->listener->close($this, $code, $reason);
$this->socket->close();
}
}

/**
Expand Down
18 changes: 9 additions & 9 deletions src/main/php/websocket/protocol/Messages.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,21 @@ public function next($socket, $i) {

case Opcodes::CLOSE: // Close connection
if ('' === $payload) {
$close= ['code' => 1000];
$close= ['code' => 1000, 'reason' => ''];
} else {
$close= unpack('ncode/a*message', $payload);
if (!preg_match('//u', $close['message'])) {
$close= ['code' => 1007];
$close= unpack('ncode/a*reason', $payload);
if (!preg_match('//u', $close['reason'])) {
$close= ['code' => 1007, 'reason' => ''];
} else if ($close['code'] > 2999 || in_array($close['code'], [1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011])) {
// Answer with client code and message
// Answer with client code and reason
} else {
$close= ['code' => 1002];
$close= ['code' => 1002, 'reason' => ''];
}
}

$conn->answer(Opcodes::CLOSE, pack('na*', $close['code'], $close['message'] ?? ''));
$this->logging->log($i, 'CLOSE', $close);
$socket->close();
$conn->answer(Opcodes::CLOSE, pack('na*', $close['code'], $close['reason']));
$this->logging->log($i, 'CLOSE', $close['code'].($close['reason'] ? ': '.$close['reason'] : ''));
$this->listeners->connections[$i]->close($close['code'], $close['reason']);
break;
}
} catch (Throwable $t) {
Expand Down
4 changes: 2 additions & 2 deletions src/test/php/websocket/unittest/WebSocketTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,14 @@ public function listening() {
public $events= [];
public function open($conn) { $this->events[]= 'open'; }
public function message($conn, $message) { $this->events[]= "message<{$message}>"; }
public function close($conn) { $this->events[]= 'close'; }
public function close($conn, $code, $reason) { $this->events[]= "close<{$code}>"; }
};

$fixture= $this->fixture("\x81\x04Test")->listening($listener);
$fixture->connect();
iterator_to_array($fixture->receive());
$fixture->close();

Assert::equals(['open', 'message<Test>', 'close'], $listener->events);
Assert::equals(['open', 'message<Test>', 'close<1000>'], $listener->events);
}
}

0 comments on commit 06527ab

Please sign in to comment.