Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReactHttp server integretion problem #188

Closed
memran opened this issue Sep 11, 2018 · 6 comments

Comments

Projects
None yet
2 participants
@memran
Copy link

commented Sep 11, 2018

i m trying to use league/route with reactphp http server. it works fine at first request.After that it gives error like this.

Error: The response callback is expected to resolve with an object implementing Psr\Http\Message\ResponseInterface, but rejected with "FastRoute\BadRouteException" instead.
Cannot register two routes matching "/" for method "GET

My complete code is like this:

`<?php

include 'vendor/autoload.php';

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use React\EventLoop\Factory;
use React\Http\Response;
use React\Http\StreamingServer;
use React\Http\Server;

$router = new League\Route\Router;

//map a route
$router->get('/', function (ServerRequestInterface $request) : ResponseInterface
{
$response = new \Zend\Diactoros\Response;
$response->getBody()->write("

Hello, World!

");
return $response;
});

$onRequest = function (ServerRequestInterface $request) use ($router){

          if($request->getUri()->getPath()== "/favicon.ico"){
                    return new Response(200);
            }
            return $router->dispatch($request);

};

$loop = Factory::create();

$server = new StreamingServer($onRequest);

$server->on('error', function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
if ($e->getPrevious() !== null) {
$previousException = $e->getPrevious();
echo $previousException->getMessage() . PHP_EOL;
}
});

$socket = new \React\Socket\Server(isset($argv[1]) ? $argv[1] : '0.0.0.0:1337', $loop);

$server->listen($socket);

echo 'Listening on ' . str_replace('tcp:', 'http:', $socket->getAddress()) . PHP_EOL;

$loop->run();
`

@philipobenito

This comment has been minimized.

Copy link
Member

commented Sep 11, 2018

The dispatcher is only actually designed to dispatch one request, as far as I can tell, this setup would be dispatching multiple times

@memran

This comment has been minimized.

Copy link
Author

commented Sep 11, 2018

yes. you are right. if i create router onRequest function then it works perfectly. I want to read all the routes from the files at once to reduce I/O. pls advise how can i implement this things ?

@philipobenito

This comment has been minimized.

Copy link
Member

commented Sep 11, 2018

@memran

This comment has been minimized.

Copy link
Author

commented Sep 11, 2018

In this way, core Fast Route library is working fine without giving any error. it dispatched when new request come and return response.

can u check pls following function.

public function dispatch(ServerRequestInterface $request) : ResponseInterface { if (is_null($this->getStrategy())) { $this->setStrategy(new ApplicationStrategy); } $this->prepRoutes($request); return (new Dispatcher($this->getData())) ->middlewares($this->getMiddlewareStack()) ->setStrategy($this->getStrategy()) ->dispatchRequest($request) ; }
On the above function, $this->prepRoutes($request); If i am not wrong, this could be call on class [with some modification] before dispatch function called as it is not associated with request.I think it is route building function. pls correct me if am wrong.

@philipobenito

This comment has been minimized.

Copy link
Member

commented Sep 11, 2018

@memran

This comment has been minimized.

Copy link
Author

commented Sep 11, 2018

ok..thanks. i have updated Router.php scripts and it works fine. just sharing with u if you find any beneficial then you can apply as patch .

`public function buildRoute(): self
{
if (is_null($this->getStrategy())) {
$this->setStrategy(new ApplicationStrategy);
}

    $this->prepRoutes();
    return $this;
}

/**
 * {@inheritdoc}
 */
public function dispatch(ServerRequestInterface $request) : ResponseInterface
{
          
    $this->processGroups($request);

    return (new Dispatcher($this->getData()))
        ->middlewares($this->getMiddlewareStack())
        ->setStrategy($this->getStrategy())
        ->dispatchRequest($request)
    ;
}

/**
 * Prepare all routes, build name index and filter out none matching
 * routes before being passed off to the parser.
 *
 * @param \Psr\Http\Message\ServerRequestInterface $request
 *
 * @return void
 */
protected function prepRoutes() : void
{
    //$this->processGroups($request);
    $this->buildNameIndex();

    $routes = array_merge(array_values($this->routes), array_values($this->namedRoutes));

    foreach ($routes as $key => $route) {
        // check for scheme condition
        if (! is_null($route->getScheme()) && $route->getScheme() !== $request->getUri()->getScheme()) {
            continue;
        }

        // check for domain condition
        if (! is_null($route->getHost()) && $route->getHost() !== $request->getUri()->getHost()) {
            continue;
        }

        // check for port condition
        if (! is_null($route->getPort()) && $route->getPort() !== $request->getUri()->getPort()) {
            continue;
        }

        if (is_null($route->getStrategy())) {
            $route->setStrategy($this->getStrategy());
        }

        $this->addRoute($route->getMethod(), $this->parseRoutePath($route->getPath()), $route);
    }
}`

Here is the application final code:

$router   = new League\Route\Router;

  //map a route
  $router->get('/', function (ServerRequestInterface $request) : ResponseInterface 
  {
          $response = new \Zend\Diactoros\Response;
          //$response = new Response();
          $response->getBody()->write('<h1>Hello, World!</h1>'.rand(10,100));
          return $response;
  });  

    $router->buildRoute();
    $response=$router->dispatch($request);
   return $response;

other way it can be done like when map and group function will be called, it will directly addRoute to the routes list.

Thanks for your quick response and great contribution to the php community.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.