证书生成

openssl ecparam -genkey -name secp384r1 -out server.key
openssl req -new -x509 -sha256 -key server.key -out server.pem -days 3650

Common Name (eg, fully qualified host name) []:test

golang 客户端连接正常

c, err := credentials.NewClientTLSFromFile("./config/server/server.pem", "test")
if err != nil {
    log.Fatalf("credentials.NewClientTLSFromFile err: %v", err)
}

conn, err := grpc.Dial(":50052", grpc.WithTransportCredentials(c))
if err != nil {
    log.Fatalf("grpc.Dial err: %v", err)
}
defer conn.Close()

client := pb.NewQueryOnlineWsClient(conn)
resp, err := client.OnlineConn(context.Background(), &pb.QueryOnlineRequest{CompanyId: 1})
if err != nil {
    log.Fatalf("client.Search err: %v", err)
}

log.Printf("resp: %s", resp.GetOnline())

PHP 客户端连接失败

/*$client = new QueryOnlineWsClient('192.168.20.10:50052', [
     'credentials' => \Grpc\ChannelCredentials::createInsecure()
]);*/

$pem = file_get_contents(storage_path("server.pem"));

$client = new QueryOnlineWsClient('192.168.20.10:50052', [
    'credentials' => \Grpc\ChannelCredentials::createSsl($pem),
    'grpc.ssl_target_name_override' => 'test',
]);

$request = new QueryOnlineRequest();

$request->setCompanyId(1);
$request->setConnKey(['1']);

list ($response, $status) = $client->OnlineConn($request)->wait();

dump($status);

输出

{#911 ▼
  +"metadata": []
  +"code": 14
  +"details": "Connect Failed"
}

总结

  • gRPC服务端如果不启用 TLS 认证 。PHP 客户端是正常连接的
  • server.pem 正确引入并保证正确
  • 在同样启用 TLS 认证, golang 客户端可以连接, PHP 无法连接

大家帮我看看,我的代码问题是出在那里呢?