首页 > 其他分享 >同一端口同一方法提供grpc和http流量支持

同一端口同一方法提供grpc和http流量支持

时间:2023-08-17 11:38:20浏览次数:36  
标签:http 同一 grpc pb func go org

项目地址 https://github.com/lesterhnu/grpcdemo

同一端口同一方法提供grpc和http流量支持_http

安装工具链

go install google.golang.org/protobuf/cmd/protoc-gen-go

go install google.golang.org/grpc/cmd/protoc-gen-go-grpc

go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway

编写proto

// hello.proto
syntax = "proto3";
package pb;

option go_package = "/pb";

service Hello {
  rpc SayHello(HelloRequest) returns(HelloResponse){}
}
message HelloRequest{
  string msg = 1;
}
message HelloResponse{
  string msg = 1;
}

生成pb.go

生成的pb.go在proto目录下,包名为 hello.proto中 option go_package指定

# 在proto目录下执行
protoc -I=.  --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
--grpc-gateway_out=. --grpc-gateway_opt=paths=source_relative  \
./*.proto

实现server的业务逻辑

// 创建文件 server/hello.go
package server

import (
  "context"
  pb "grpcdemo/proto"
)

type HelloServer struct {
  pb.UnimplementedHelloServer
}

func NewHelloServer() *HelloServer {
  return &HelloServer{}
}
func (h *HelloServer) Greet(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {
  return &pb.HelloResponse{Msg: "test"}, nil
}

main.go 文件中启动服务

package main

import (
  "context"
  "github.com/grpc-ecosystem/grpc-gateway/runtime"
  "golang.org/x/net/http2"
  "golang.org/x/net/http2/h2c"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials/insecure"
  "google.golang.org/grpc/reflection"
  pb "grpcdemo/proto"
  "grpcdemo/server"
  "log"
  "net/http"
  "strings"
)

const PORT = "8888"

func main() {
  err := RunServer()
  if err != nil {
    panic(err)
  }
}

func RunServer() error {
  httpMux := runHttpServer()
  grpcS := runGrpcServer()
  gatewayMux := runGatewayServer()

  httpMux.Handle("/", gatewayMux)

  return http.ListenAndServe(":"+PORT, grpcHandlerFunc(grpcS, httpMux))
}
func runGrpcServer() *grpc.Server {
  s := grpc.NewServer()
  pb.RegisterHelloServer(s, server.NewHelloServer())
  reflection.Register(s)
  return s
}
func runHttpServer() *http.ServeMux {
  s := http.NewServeMux()
  return s
}
func runGatewayServer() *runtime.ServeMux {
  endpoint := ":" + PORT
  gwmux := runtime.NewServeMux()
  options := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
  err := pb.RegisterHelloHandlerFromEndpoint(context.Background(), gwmux, endpoint, options)
  if err != nil {
    log.Fatal(err)
  }
  return gwmux
}
func grpcHandlerFunc(grpcServer *grpc.Server, httpHandler http.Handler) http.Handler {
  return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.ProtoMajor == 2 && strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
      grpcServer.ServeHTTP(w, r)
    } else {
      httpHandler.ServeHTTP(w, r)
    }
  }), &http2.Server{})
}

测试响应

http调用

curl -X POST http://localhost:8888/sayHello
---
{
  "msg": "hello !"
}

grpc调用

新建client/main.go文件

// client/main.go
package main

import (
  "context"
  "google.golang.org/grpc"
  "google.golang.org/grpc/credentials/insecure"
  pb "grpcdemo/proto"
  "log"
)

func main() {
  conn, _ := grpc.Dial("localhost:8888", grpc.WithTransportCredentials(insecure.NewCredentials()))
  c := pb.NewHelloClient(conn)
  ctx := context.Background()
  resp, err := c.SayHello(ctx, &pb.HelloRequest{Msg: "123"})
  if err != nil {
    log.Println(err)
    return
  }
  log.Println(resp.Msg)
}

标签:http,同一,grpc,pb,func,go,org
From: https://blog.51cto.com/u_16228798/7119663

相关文章

  • 高效的HTTP代理,python如何助力
    在使用Python编写高效的HTTP代理时,可以采用以下一些小技巧来提升性能和效率:1、使用异步请求库:使用异步的HTTP请求库,如aiohttp或httpx,可以实现并发处理多个请求,提高代理的吞吐量和响应速度。2、复用连接:在处理多个请求时,尽量复用已建立的连接,而不是每次请求都创建新的连接。这可以通......
  • 在html5中播放RTSP/RTMP/HLS/HTTP视频流媒体的几种方案,并支持H.265
    经过多年的项目实战和研发经验的积累,总结了一下对于H5视频可视化在视频播放上如何做到无插件H5展示的方法,尤其是契合安防行业的方案;除了HTTP、WebSocket类的传输协议,其他是无法通用地传输到浏览器的,所以,如果要做一款通用的H5视频播放器,基本上就是一款HTTP/WebSocket协议的视频播放......
  • unity文件下载HttpWebRequest
    ///<summary>///下载进度///</summary>publicfloatProgress{get;privateset;}///<summary>///下载状态///</summary>publicintStatus{get;privateset;}///&......
  • mormot2 笔记(二) Http服务的简单搭建
    mormot2框架中有个THttpServer类,它有一个Router属性,定义如下:propertyRouter:TUriRouterreadfRoute;Router是添加路由的入口点,它有和http协议对应的get,post,put,delete等方法,这些方法可以添加路由,下面常用的get方法定义。procedureGet(constaUri:RawUtf8;......
  • (随笔)龟兔赛跑(多线程调用同一资源时一个线程结束时其他线程保持运行)
    问题:当其一线程结束运行后其他线程保持运行而非结束现象:控制台会输出两次thewinneris:xxx代码如下packagecom.demo01;/***TODO模拟归途赛跑**@authorpangyangjian*@since2023/8/1616:10*/publicclassTextThread_5implementsRunnable{ @Override......
  • 微信小程序生成外部http短链
    微信小程序通过外部链接动态访问到某个小程序的某个页面(只支持非个人小程序,个人小程序需要一个非个人小程序做跳板);方案一(免费、有50w条限制): 通过微信官方给的api生成短链;api1:生成token,点击链接查看官方文档https://api.weixin.qq.com/cgi-bin/token?grant_type=client_creden......
  • nginx把http迁移到https
    买的证书是阿里云提供的server{#HTTPS的默认访问端口443。#如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。listen443ssl;#填写证书绑定的域名server_name<yourdomain>;#填写证书文件名称ssl_certificate......
  • ThingsKit物联网平台模拟HTTP设备接入
    准备工作POSTMAN设备模拟工具下载POSTMAN是一款支持HTTP协议的接口调试与测试工具,其主要特点就是功能强大,使用简单且易用性好。无论是开发人员进行接口调试,还是测试人员做接口测试,POSTMAN都是首选工具之一。Postman平台创建虚拟设备创建直连测试产品:::info......
  • http实现大文件上传
    ​文件夹数据库处理逻辑public class DbFolder{    JSONObjectroot;       public DbFolder()    {        this.root= new JSONObject();        this.root.put("f_id", "");        this.root.put("f_nameLoc", "根......
  • SRS使用Https配置实现远程推流
    一、启动SRS具体如何搭建SRS环境,请查看之前的文章。执行以下命令启动SRS:dockerrun--rm-it-p1935:1935-p1985:1985-p8080:8080registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5./objs/srs-cconf/docker.conf二、启动信令服务器执行以下命令启动信令服务器:dockerrun......