amphp / websocket-server

WebSocket component for PHP based on the Amp HTTP server.
MIT License
114 stars 17 forks source link

Fatal Error running the example #16

Closed DrLightman closed 4 years ago

DrLightman commented 4 years ago

Trying to bring up a "simple" PHP server similar to the one for the tcp chat example but with WebSockets.

The output with the errors:

D:\sites\amphpws>php app.php
PHP Fatal error:  Class class@anonymous may not inherit from final class
 (Amp\Websocket\Server\Websocket) in D:\sites\amphpws\app.php on line 28

Fatal error: Class class@anonymous may not inherit from final class
 (Amp\Websocket\Server\Websocket) in D:\sites\amphpws\app.php on line 28

Line 28 is:

$websocket = new class extends Websocket {

My composer.json:

{
    "require": {
        "amphp/websocket-server": "^2",
        "amphp/http-server-router": "^1",
        "amphp/http-server-static-content": "^1",
        "amphp/log": "^1"
    },
    "minimum-stability": "RC"
}

My app.php:

<?php

// Note that this example requires:
// amphp/http-server-router
// amphp/http-server-static-content
// amphp/log

use Amp\Http\Server\HttpServer;
use Amp\Http\Server\Request;
use Amp\Http\Server\Response;
use Amp\Http\Server\Router;
use Amp\Http\Server\StaticContent\DocumentRoot;
use Amp\Log\ConsoleFormatter;
use Amp\Log\StreamHandler;
use Amp\Loop;
use Amp\Promise;
use Amp\Socket\Server as SocketServer;
use Amp\Success;
use Amp\Websocket\Client;
use Amp\Websocket\Message;
use Amp\Websocket\Server\Websocket;
use Monolog\Logger;
use function Amp\ByteStream\getStdout;
use function Amp\call;

require __DIR__ . '/vendor/autoload.php';

$websocket = new class extends Websocket {
    public function handleHandshake(Request $request, Response $response): Promise
    {
        if (!\in_array($request->getHeader('origin'), ['http://localhost:1337', 'http://127.0.0.1:1337', 'http://[::1]:1337'], true)) {
            $response->setStatus(403);
        }

        return new Success($response);
    }

    public function handleClient(Client $client, Request $request, Response $response): Promise
    {
        return call(function() use ($client): \Generator {
            while ($message = yield $client->receive()) {
                \assert($message instanceof Message);
                $this->broadcast(\sprintf('%d: %s', $client->getId(), yield $message->buffer()));
            }
        });
    }
};

Loop::run(function () use ($websocket): Promise {
    $sockets = [
        SocketServer::listen('127.0.0.1:1337'),
        SocketServer::listen('[::1]:1337'),
    ];

    $router = new Router;
    $router->addRoute('GET', '/broadcast', $websocket);
    $router->setFallback(new DocumentRoot(__DIR__ . '/public'));

    $logHandler = new StreamHandler(getStdout());
    $logHandler->setFormatter(new ConsoleFormatter);
    $logger = new Logger('server');
    $logger->pushHandler($logHandler);

    $server = new HttpServer($sockets, $router, $logger);

    return $server->start();
});

My OS: Windows 10 Pro 64

My PHP: PHP 7.4.2 thread safe x64

trowski commented 4 years ago

Fixed example for v2.0.0-rc2 in readme with ed408970287bd710a35f1d110005a18c39dab987.