配置http 服务
下载包
go install \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
google.golang.org/protobuf/cmd/protoc-gen-go \
google.golang.org/grpc/cmd/protoc-gen-go-grpc
编译
-
将
third_party/googleapis
拷贝到proto目录下
-
修改
.proto
文件syntax="proto3"; package service; option go_package = "gaodongfei.com/service"; import "google/api/annotations.proto"; message ProdRequest{ int32 prod_id=1; } message ProdResponse{ int32 prod_stock=1; } service ProdService{ rpc GetProdStock(ProdRequest)returns(ProdResponse){ option(google.api.http) = { get: "/v1/prod/{prod_id}" }; } }
-
生成文件
protoc --go_out=plugins=grpc:../service \ --go_opt paths=source_relative \ Prod.proto protoc -I . --grpc-gateway_out ../service \ --grpc-gateway_opt logtostderr=true \ --grpc-gateway_opt paths=source_relative \ --grpc-gateway_opt generate_unbound_methods=true \ Prod.proto
配置客户端证书
将客户端证书移至证书目录,http server需要使用证书访问gRPC 服务器
封装获取证书函数
helper.go
package helper
import (
"crypto/tls"
"crypto/x509"
"google.golang.org/grpc/credentials"
"io/ioutil"
)
// 获取服务器端书
func GetServerCert() credentials.TransportCredentials{
cert,_ := tls.LoadX509KeyPair("cert/server.pem","cert/server.key")
// 创建一个新的、空的 CertPool
certPool := x509.NewCertPool()
ca,_ := ioutil.ReadFile("cert/ca.pem")
//尝试解析所传入的 PEM 编码的证书。如果解析成功会将其加到 CertPool 中,便于后面的使用
certPool.AppendCertsFromPEM(ca)
//构建基于 TLS 的 TransportCredentials 选项
creds := credentials.NewTLS(&tls.Config{
//设置证书链,允许包含一个或多个
Certificates: []tls.Certificate{cert},
//要求必须校验客户端的证书。可以根据实际情况选用以下参数
ClientAuth: tls.RequireAndVerifyClientCert,
//设置根证书的集合,校验方式使用 ClientAuth 中设定的模式
ClientCAs: certPool,
})
return creds
}
// 获取客户端证书
func GetClientCert() credentials.TransportCredentials{
//从证书相关文件中读取和解析信息,得到证书公钥、密钥对
cert,_ := tls.LoadX509KeyPair("cert/client.pem","cert/client.key")
// 创建一个新的、空的 CertPool
certPool := x509.NewCertPool()
ca,_ := ioutil.ReadFile("cert/ca.pem")
//尝试解析所传入的 PEM 编码的证书。如果解析成功会将其加到 CertPool 中,便于后面的使用
certPool.AppendCertsFromPEM(ca)
//构建基于 TLS 的 TransportCredentials 选项
creds := credentials.NewTLS(&tls.Config{
//设置证书链,允许包含一个或多个
Certificates: []tls.Certificate{cert},
//要求必须校验客户端的证书。可以根据实际情况选用以下参数
ServerName: "localhost",
RootCAs:certPool,
})
return creds
}
创建http server
httpserver.go
package main
import (
"context"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"log"
"net/http"
"serverGrpc/helper"
gw "serverGrpc/service" // Update
)
func main(){
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithTransportCredentials(helper.GetClientCert())}
err := gw.RegisterProdServiceHandlerFromEndpoint(context.Background(), mux, "localhost:8081",opts)
if err != nil {
log.Fatal(err)
return
}
// Start HTTP server (and proxy calls to gRPC server endpoint)
http.ListenAndServe(":8080", mux)
}
错误:
字面意思是地址不可用,经过分析是端口8081占了,而导致的
panic: runtime error: invalid memory address or nil pointer dereference
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x14553ed]
goroutine 1 [running]:
google.golang.org/grpc.(*listenSocket).Close(0xc00019c400, 0xc000139530, 0xc000197bf8)
/Users/a/go/pkg/mod/google.golang.org/grpc@v1.34.0/server.go:679 +0x2d
google.golang.org/grpc.(*Server).Serve.func2(0xc00017c540, 0xc00019c400)
/Users/a/go/pkg/mod/google.golang.org/grpc@v1.34.0/server.go:723 +0xec
panic(0x14f6d00, 0x19015f0)
/usr/local/go/src/runtime/panic.go:969 +0x175
google.golang.org/grpc.(*Server).Serve(0xc00017c540, 0x0, 0x0, 0x0, 0x0)
/Users/a/go/pkg/mod/google.golang.org/grpc@v1.34.0/server.go:732 +0x204
main.main()
/Users/a/go/src/server/main.go:18 +0xef
exit status 2