Menu
Reference
- Manticore\Ds
- Async
- Http
- Http\WebSocket
- Interfaces
- Handler
- Classes
- Connection
- ConnectionClosedException
- HandshakeException
- Hub
- Message
- Options
- Functions
- connect()
- handler()
- run()
- upgrade()
- Buffer
- Process
- Io\Poll
- Manticore\Sapi
- Ffi
Handler
interface
interface Handler
Event callbacks for a connection, as an alternative to a foreach loop.
Implement it and pass it to handler() (server, as the session of upgrade()) or run() (client). The calls arrive in this order: onOpen once, onMessage per message, onClose once, whichever way the connection ends.
Example
// Callback style: a Handler on each side, and a Hub that fans a message out.
use function Async\async;
use function Async\spawn;
use Http\WebSocket as WS;
final class Greeter implements WS\Handler
{
public function __construct(private WS\Hub $hub) {}
public function onOpen(WS\Connection $c): void
{
$this->hub->add($c);
$c->send('welcome');
}
public function onMessage(WS\Connection $c, WS\Message $m): void
{
$n = $this->hub->broadcast('said: ' . $m->data);
echo "server: broadcast to $n\n";
}
public function onClose(WS\Connection $c, int $code, string $reason): void
{
$this->hub->remove($c);
echo "server: closed with $code '$reason', hub has ", $this->hub->count(), "\n";
}
public function onError(WS\Connection $c, \Throwable $e): void
{
echo "server: error ", $e->getMessage(), "\n";
}
}
$l = stream_socket_server('tcp://127.0.0.1:0');
stream_set_blocking($l, false);
$name = stream_socket_get_name($l, false);
$port = (int)substr($name, strrpos($name, ':') + 1);
$server = \Http\Server::onListener($l)->acceptWait(0.02);
$hub = new WS\Hub();
async(function () use ($server, $port, $hub) {
spawn(function () use ($server, $hub) {
$server->serve(function (\Http\Request $req) use ($hub): \Http\Response {
return WS\upgrade($req, WS\handler(new Greeter($hub)));
});
});
$ws = WS\connect("ws://127.0.0.1:$port/");
$m = $ws->receive();
echo 'client: ', $m->data, "\n";
$ws->send('hi');
$m = $ws->receive();
echo 'client: ', $m->data, "\n";
$ws->close(4000, 'bye');
\Async\delay(0.05);
echo 'client: peer close code ', $ws->closeCode(), "\n";
$server->stop();
});Output
client: welcome
server: broadcast to 1
client: said: hi
server: closed with 4000 'bye', hub has 0
client: peer close code 4000Methods
onOpen() | The connection is ready; called before the first message is read. |
onMessage() | A complete message arrived. |
onClose() | The connection ended; called exactly once, after any onError. |
onError() | onOpen or onMessage threw; the connection is then closed with 1011. |
onOpen()#source
function onOpen(Connection $c): void
The connection is ready; called before the first message is read.
Parameters
$cConnection- the connection
onMessage()#source
function onMessage(Connection $c, Message $m): void
A complete message arrived.
Parameters
$cConnection- the connection
$mMessage- the message
onClose()#source
function onClose(Connection $c, int $code, string $reason): void
The connection ended; called exactly once, after any onError.
Parameters
$cConnection- the connection
$codeint- the peer's close code (see Connection::closeCode(); 1006 if no Close arrived)
$reasonstring- the peer's close reason, possibly empty
onError()#source
function onError(Connection $c, \Throwable $e): void
onOpen or onMessage threw; the connection is then closed with 1011. An exception thrown by onError itself is discarded.
Parameters
$cConnection- the connection
$e\Throwable- the exception