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
Closed

ReactHttp server integretion problem #188

memran opened this issue Sep 11, 2018 · 6 comments

Comments

@memran
Copy link

@memran memran 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
Copy link
Member

@philipobenito philipobenito 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
Copy link
Author

@memran memran 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
Copy link
Member

@philipobenito philipobenito commented Sep 11, 2018

@memran
Copy link
Author

@memran memran 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
Copy link
Member

@philipobenito philipobenito commented Sep 11, 2018

@memran
Copy link
Author

@memran memran 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
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants