services目录下grpc demo是否需要另外启动swoole的http2服务端?
sj8354661 opened this issue · comments
通过http://主机:9501/grpc访问。
经调试后发现streamid始终为0,服务端好像是没有启动。
在env配置文件中设置SERVER_OPEN_HTTP2=1,结果还是一样。
于是单独建立了一个swoole http2 server的启动文件执行,结果有响应了。
建立的启动文件如下(只是简单测试一下,没仔细调整,直接修改自grpc库中的example文件):
`
use Helloworld\HelloReply;
use Helloworld\HelloRequest;
require dirname(DIR, 3) . '/vendor/autoload.php';
$http = new swoole_http_server('0.0.0.0', 50051, SWOOLE_BASE);
$http->set([
'log_level' => SWOOLE_LOG_INFO,
'trace_flags' => 0,
'worker_num' => 1,
'open_http2_protocol' => true
]);
$http->on('workerStart', function (swoole_http_server $server) {
echo "php " . DIR . "/greeter_client.php\n";
});
$http->on('request', function (swoole_http_request $request, swoole_http_response $response) use ($http) {
$path = $request->server['request_uri'];
echo "\n --greeter_server path: $path";
$route = [
'/helloworld.Greeter/SayHello' => function (...$args) {
[$server, $request, $response] = $args;
/**@var $request_message HelloRequest */
$request_message = Grpc\Parser::deserializeMessage([HelloRequest::class, null], $request->rawContent());
if ($request_message) {
$response_message = new HelloReply();
$response_message->setMessage('Hello ' . $request_message->getName());
$response->header('content-type', 'application/grpc');
$response->header('trailer', 'grpc-status, grpc-message');
$trailer = [
"grpc-status" => "0",
"grpc-message" => ""
];
foreach ($trailer as $trailer_name => $trailer_value) {
$response->trailer($trailer_name, $trailer_value);
}
$response->end(Grpc\Parser::serializeMessage($response_message));
return true;
}
return false;
}
];
if (!(isset($route[$path]) && $route[$path]($http, $request, $response))) {
$response->status(400);
$response->end('Bad Request');
}
});
$http->start();
`
请问是否需要建立一个类似上面这样的关于swoole http2的单独的启动文件,并启动,才能使用grpc。
不需要,提供下你用的版本和streamid=0的重现代码
swoole 4.4.3
http2 => enabled
nghttp2 1.39.1
.env配置:
SERVER_OPEN_HTTP2=1
SERVER_TASK_ENABLE_COROUTINE=1
SERVER_MAX_REQUEST=99
SERVER_TASK_WORKER_NUM=9
server.php配置:
'open_http2_protocol' => envBool('SERVER_OPEN_HTTP2', true),
浏览器访问:
http://localhost:9501/grpc
打印相关文件中的相关变量:
++\sw-fw-less-app\app\grpc-gen\Demo\GreetingClient.php GreetingClient __construct hostname: string(15) "127.0.0.1:50051"
++\luoxiaojun\grpc\src\Grpc\Client.php Client __construct hostname: string(15) "127.0.0.1:50051"
++\luoxiaojun\grpc\src\Grpc\BaseStub.php grpc BaseStub _simpleRequest request: object(Swoole\Http2\Request)#433 (6) {
["path"]=>
string(23) "/demo.Greeting/SayHello"
["method"]=>
string(4) "POST"
["headers"]=>
array(2) {
["content-type"]=>
string(16) "application/grpc"
["te"]=>
string(8) "trailers"
}
["cookies"]=>
NULL
["data"]=>
string(11) "�
�ping"
["pipeline"]=>
bool(false)
}
++\luoxiaojun\grpc\src\Grpc\Client.php Client send isconnect: NULL
++\luoxiaojun\grpc\src\Grpc\BaseStub.php grpc BaseStub _simpleRequest streamId: int(0)
++\luoxiaojun\grpc\src\Grpc\Client.php grpc Client recv streamId: int(0)
++\luoxiaojun\grpc\src\Grpc\Parser.php parseToResultArray: no response!bool(false)
可以看到 _simpleRequest发出了http2的请求,但是swoole没有响应。
sw-fw-less 和 sw-fw-less-app 都是前天下载的,代码只修改了autoload的路径。
将luoxiaojun\grpc\src\Grpc\Client.php文件,start函数下的return false注释后。在后面的debug代码中输出了错误信息。
注释的位置:
if (!$this->client->connect()) { //return false; }
输出的错误信息:
var_dump($this->client->errCode);
int(104)
var_dump($this->client->errMsg);
string(33) "client is not connected to server"
问题解决了。
修改下面这个文件里的端口设置:
\luoxiaojun\grpc\src\Grpc\ClientStub.php
$endpoint = '127.0.0.1:50051'; 修改为: $endpoint = '127.0.0.1:9501';
之前一直以为grpc和swoole使用不同的端口,没想过要修改这里。