laravelgrpclaravel-octaneroadrunner

Install laravel octane with roadrunner server, gRPC plugin


I'm using laravel 11.9. I want to use laravel octane with gRPC plugin but it not work. my composer.json file

...
"require": {
        "php": "^8.2",
        "ext-grpc": "*",
        "google/protobuf": "^3.25",
        "grpc/grpc": "^1.57",
        "laravel/framework": "^11.9",
        "laravel/octane": "^2.3",
        "laravel/tinker": "^2.9",
        "spiral/goridge": "^4.2",
        "spiral/roadrunner": "^2024.1",
        "spiral/roadrunner-cli": "^2.6.0",
        "spiral/roadrunner-grpc": "^3.3",
        "spiral/roadrunner-http": "^3.3.0"
    },
...

my voucher.proto file


package services;

option php_namespace = "GrpcServices\\Voucher\\Messages";
option php_metadata_namespace = "GrpcServices\\Voucher";

service Voucher {
    rpc validateVoucher (VoucherMessageRequest) returns (VoucherMessageResponse) {
    }
}

message VoucherMessageRequest {
    repeated int32 VoucherId = 1;
}

message VoucherMessageResponse {
    int32 VoucherId = 1;
    int32 customerId = 2;
}

my voucher service


namespace App\Grpc;

use GrpcServices\Voucher\Messages\VoucherMessageRequest;
use GrpcServices\Voucher\Messages\VoucherMessageResponse;
use Spiral\Roadrunner\GRPC\ContextInterface;

class VoucherService implements VoucherServiceInterface
{
    public function validateVoucher(VoucherMessageRequest $request, ContextInterface $context): VoucherMessageResponse
    {
        $response = new VoucherMessageResponse();

        return $response;
    }
}

after I run command:

protoc --proto_path=./protos --php_out=./app/Grpc --grpc_out=./app/Grpc --plugin=protoc-gen-grpc=/usr/bin/grpc_php_plugin voucher.proto

I got 4 files VoucherClient.php, VoucherMessageRequest.php, VoucherMessageResponse.php, Voucher.php, like this

app
 -Grpc
   |
    -GrpcServices
      |
       - Voucher
          |
           - Messages
          |    - VoucherClient.php
          |    - VoucherMessageRequest.php
          |    - VoucherMessageResponse.php
           - Voucher.php

.rr.yaml file

version: "3"
rpc:
  listen: "tcp://127.0.0.1:6001"

server:
  command: "php artisan octane:start --server=roadrunner --host=127.0.0.1 --port=8000"

http:
  address: "0.0.0.0:8000"

grpc:
  listen: "tcp://0.0.0.0:9090"
  proto:
    - "/var/www/html/server/protos/voucher.proto"

logs:
  mode: development

  channels:
    grpc:
      level: debug
      type: stdout
    http:
      level: debug
      type: stdout
    server:
      level: debug
      type: stdout

now I run ./rr serve have an error

/var/www/html/server # ./rr serve -p
2024-06-06T07:59:27+0000        DEBUG   rpc             plugin was started      {"address": "tcp://127.0.0.1:6001", "list of the plugins with RPC methods:": ["lock", "resetter", "app", "informer"]}
handle_serve_command: Function call error:
        serve error from the plugin *grpc.Plugin stopping execution, error: grpc_plugin_serve: WorkerAllocate:
        static_pool_allocate_workers:
        goridge_frame_receive: validation failed on the message sent to STDOUT, see: https://roadrunner.dev/docs/known-issues-stdout-crc/current/en, invalid message:
   ERROR  RoadRunner server is already running.

and stop process. if I run php artisan octane:start --server=roadrunner --host=127.0.0.1 --port=8000 it work with a message

/var/www/html/server #  php artisan octane:start --server=roadrunner --host=127.0.0.1 --port
=8000

   INFO  Server running…

  Local: http://127.0.0.1:8000

  Press Ctrl+C to stop the server

In client I write a test command:

<?php

namespace App\Console\Commands;

use GrpcServices\Voucher\Messages\VoucherClient;
use GrpcServices\Voucher\Messages\VoucherMessageRequest;
use Illuminate\Console\Command;
class test extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:test';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $client = new VoucherClient('127.0.0.1:9090', [
            'credentials' => \Grpc\ChannelCredentials::createInsecure(),
        ]);
        $voucherRequest = new VoucherMessageRequest();
        $voucherRequest->setVoucherId([123]);

        list($response, $status) = $client->validateVoucher($voucherRequest)->wait();
        dd($response, $status);
    }
}

and when run php artisan app:test I got an error message

/var/www/html/client # php artisan app:test
null // app/Console/Commands/test.php:36
{#566
  +"metadata": []
  +"code": 13
  +"details": "sync_worker_receive_frame: Network: EOF"
} // app/Console/Commands/test.php:36

I don't know command ./rr serve or php artisan octane:start --server=roadrunner --host=127.0.0.1 --port=8000 is right? How to laravel octane work with gRPC?

There is very little documentation on this issue

How to laravel octane work with gRPC?


Solution

  • Laravel Octane doesn't support gRPC. Moreover, as per this reply link, in Laravel, they don't understand what is it.

    As for the error message you see in the logs, this is the reason:

    ERROR  RoadRunner server is already running.
    

    You can't send any data into RR's STDOUT while workers are booting (it is fine to use STDERR).