#1 安装 protobuf
- 1.How to Install Latest Protobuf on Ubuntu 18.04
sudo apt-get install autoconf automake libtool curl make g++ unzip -y
git clone https://github.com/google/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure
make
make check
sudo make install
sudo ldconfig
#1 下载 https://github.com/protocolbuffers/protobuf/releases
mkdir temp
cd temp
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-all-3.17.3.tar.gz
tar -zxvf protobuf-all-3.17.3.tar.gz
cd protobuf-all-3.17.3
./configure
make
make check
sudo make install
sudo ldconfig # refresh shared library cache.
#2 安装 protobuf golang 插件
vagrant@homestead:/var/gin-vue/top/server$ go mod tidy
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
#3 go版本gRpc服务端和客户端demo
#1 proto文件编写以及自动生成go代码
// 在pb/ctrip/hotel 新建文件 ct_sub_hotel.proto
syntax = "proto3";
package hotel;
option go_package = "./";
// 定义服务
service SubHotel {
rpc CreateSubHotel(SubHotelRequest) returns (SubHotelReplay) {}
}
// 请求体的结构体
message SubHotelRequest {
int64 hotelId = 1;
}
// 响应的结构体
message SubHotelReplay {
string message = 1;
int64 code = 2;
}
# 在pb/ctrip/hotel 目录中输入命令
# 如果报错`protoc-gen-go: unable to determine Go import path for "ct_sub_hotel.proto"`
# 需要在上面文件中加入 option go_package = "./";
vagrant@homestead:/var/gin-vue/top/server/pb/ctrip/hotel$ protoc --go_out=plugins=grpc:. ct_sub_hotel.proto
## 或者在上面文件中加入 option go_package = "ctrip/hotel";
vagrant@homestead:/var/gin-vue/top/server/pb$ protoc --go_out=plugins=grpc:. ctrip/hotel/*.proto
##
vagrant@homestead:/var/gin-vue/top/server/pb$ protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
ctrip/hotel/*.proto
#2 服务器端代码
server/debug/gRpc/server/main.go
package main
import (
"context"
"fmt"
pb "gin-vue-admin/pb/ctrip/hotel"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"log"
"net"
)
type server struct {}
// 实现SubHotelServer接口
func (s *server) CreateSubHotel(ctx context.Context, in *pb.SubHotelRequest) (*pb.SubHotelReplay, error) {
return &pb.SubHotelReplay{Message: fmt.Sprintf("需要新增的子酒店ID:%d", in.HotelId), Code: 200}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v\n", err)
}
s := grpc.NewServer()
pb.RegisterSubHotelServer(s, &server{})
// 在 server 中 注册 gRPC 的 reflection service
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to server: %v\n", err)
}
}
#3 gin客户端代码
package main
import (
"fmt"
pb "gin-vue-admin/pb/ctrip/hotel"
"github.com/gin-gonic/gin"
"google.golang.org/grpc"
"log"
"net/http"
"strconv"
)
func main() {
r := gin.Default()
r.GET("/rpc/ctrip/hotel/create-sub-hotel", func(c *gin.Context) {
createSubHotel(c)
})
// Run http server
if err := r.Run(":8052"); err != nil {
log.Fatalf("could not run server: %v", err)
}
}
func createSubHotel(c *gin.Context) {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("Connection err:%v\n", err)
}
defer conn.Close()
client := pb.NewSubHotelClient(conn)
hotelId, _ := strconv.ParseInt(c.DefaultQuery("hotelId", "17555"), 10, 64)
req := &pb.SubHotelRequest{
HotelId: hotelId,
}
res, err := client.CreateSubHotel(c, req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"result": fmt.Sprint(res.Message),
"code": fmt.Sprint(res.Code),
})
}
#4 测试
# bash1
vagrant@homestead:/var/gin-vue/top/server/debug/gRpc/server$ go run main.go
# bash2
vagrant@homestead:/var/gin-vue/top/server/debug/gRpc/client$ go run main.go
# chrom访问接口地址
# http://192.168.10.10:8052/rpc/ctrip/hotel/create-sub-hotel?hotelId=17587
#{
# "code": "200",
# "result": "需要新增的子酒店ID:17587"
#}
#4 php-gRpc客户端
#1 安装过程
## 解决错误 php7.2-dev : Depends: libssl-dev but it is not going to be installed
sudo apt list | grep php | grep dev
sudo apt-get update
#sudo apt-get install php-common
#依据sudo apt-get install libssl-dev的报错信息安装
#libssl-dev : Depends: libssl1.1 (= 1.1.1-1ubuntu2.1~18.04.9) but 1.1.1d-1+ubuntu18.04.1+deb.sury.org+2 is to be installed
sudo apt-get install libssl1.1=1.1.1-1ubuntu2.1~18.04.9
sudo apt-get install libssl-dev
sudo apt-get install php7.2-dev
# 看是否安装成功
phpize -v
# 安装php-gRpc
sudo pecl install grpc
# 安装php-protobuf
sudo pecl install protobuf
# 如果遇到错误 fatal error: zlib.h: No such file or directory
sudo apt-get install zlib1g-dev
## php.ini地址/etc/php/7.2/fpm/pool.d/www.conf
cd /etc/php/7.2
sudo vim mods-available/grpc.ini
####写入以下信息
extension=grpc.so
####
sudo vim mods-available/protobuf.ini
####写入以下信息
extension=protobuf.so
####
# 写入软链接
sudo ln -s /etc/php/7.2/mods-available/grpc.ini cli/conf.d/20-grpc.ini
sudo ln -s /etc/php/7.2/mods-available/grpc.ini fpm/conf.d/20-grpc.ini
sudo ln -s /etc/php/7.2/mods-available/protobuf.ini cli/conf.d/20-protobuf.ini
sudo ln -s /etc/php/7.2/mods-available/protobuf.ini fpm/conf.d/20-protobuf.ini
# 验证
php -m | grep grpc
php -m | grep protobuf
# fpm重启
sudo service php7.2-fpm restart
sudo service nginx restart
#2 自行编译方式安装
# php-gRpc pecl地址:https://pecl.php.net/package/gRPC
wget https://pecl.php.net/get/grpc-1.38.0.tgz
tar -zxvf grpc-1.38.0.tgz
/usr/bin/phpize #(这个根据`phpize`实际情况来)
./configure --with-php-config=/usr/bin/php-config #(这个根据`php-config`实际情况来)
make && make install
vim /etc/php/7.2/mods-available/grpc.ini #这个根据实际情况去决定 是改`php.ini`还是别的什么
写入 extension=grpc.so
如果没有将grpc.so写入到lib中则自行拷贝
vagrant@homestead:~/temp/grpc-1.38.0$sudo cp modules/grpc.so /usr/lib/php/20170718/grpc.so
#3 安装protoc-gen-php 扩展
$ git clone --recurse-submodules -b v1.38.0 https://github.com/grpc/grpc
## 国内环境经常会卡在 --recurse-submodules 如果克隆完成,子模块更新失败则cd进入后
$ git submodule update --init
$ cd grpc
$ mkdir -p cmake/build
$ pushd cmake/build
$ cmake ../..
$ make protoc grpc_php_plugin
$ popd
#4 生成php版客户端代码
~/temp/grpc/cmake/build$ sudo cp grpc_php_plugin /usr/local/bin/
~/code/top/pb$ protoc --php_out=./ --grpc_out=./ --plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin ct_sub_hotel.proto
##
~/code/top$ protoc --php_out=./app/Libs/Grpc --grpc_out=./app/Libs/Grpc --plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin ./app/Libs/Grpc/proto/hotel.proto
如果报
app/Libs/Grpc/proto/hotel.proto:9:1: Import "google/api/annotations.proto" was not found or had errors.
错误,需要去https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto
下载相关的proto
文件,放在与app
文件夹平行的地方
#5 添加composer相关依赖
composer require google/protobuf
composer require grpc/grpc
composer require google/common-protos
#6 php代码
use Pb\Ctrip\Hotel\Ct_sub_hotel\Proto\SubHotelClient;
use Pb\Ctrip\Hotel\Ct_sub_hotel\Proto\SubHotelRequest;
class GrpcController extends BaseController
{
private function gRpc(Request $request)
{
$client = new SubHotelClient("127.0.0.1:50051", [
'credentials' => \Grpc\ChannelCredentials::createInsecure(),
]);
$subHotelRequest = new SubHotelRequest();
$subHotelRequest->setHotelId($request->get("hotelId", 999));
$call = $client->CreateSubHotel($subHotelRequest);
[$reply, $status] = $call->wait();
$message = $reply->getMessage();
$code = $reply->getCode();
return [
'message' => $message,
'code' => $code,
];
}
}
- 输出结果
{
"message": "需要新增的子酒店ID:16056",
"code": 200
}
#7 参考资料
#4 安装 Buf
#1 安装brew
## https://brew.sh/index_zh-cn
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
#2 安装Buf
## https://docs.buf.build/installation#from-source
GO111MODULE=on GOBIN=/usr/local/bin go install \
github.com/bufbuild/buf/cmd/buf \
github.com/bufbuild/buf/cmd/protoc-gen-buf-breaking \
github.com/bufbuild/buf/cmd/protoc-gen-buf-lint
#5 日常一键生成命令
#1 生成proto和service命令
## 安装Kratos
go install github.com/go-kratos/kratos/cmd/kratos/v2@latest
kratos upgrade
# 2 通过Kratos生成proto
kratos proto add api/proto/sp/meituan/v1/hotel_room_status.proto
# 3 通过Kratos生成service
kratos proto server api/proto/sp/meituan/v1/hotel_room_status.proto -t grpc/internal/service/sp
#2 buf生成go-gRpc代码
buf.yaml
version: v1beta1
name: buf.build/gin-vue-admin/top
deps:
- buf.build/beta/googleapis
build:
roots:
- api/proto/ota/ctrip/v1
buf.gen.yaml
version: v1beta1
plugins:
- name: go
#out: api/proto/ota/ctrip/v1
out: api/proto/sp/meituan/v1
opt: paths=source_relative
- name: go-grpc
#out: api/proto/ota/ctrip/v1
out: api/proto/sp/meituan/v1
opt: paths=source_relative,require_unimplemented_servers=false
- name: grpc-gateway
#out: api/proto/ota/ctrip/v1
out: api/proto/sp/meituan/v1
opt: paths=source_relative
# https://grpc-ecosystem.github.io/grpc-gateway/docs/tutorials/adding_annotations/
# https://docs.buf.build/installation/#from-source
buf beta mod update
buf generate