9 人团本之基于 HTTP2 搬一个 RPC 的砖 | 水木双

代码链接: HalokidRPC

协议格式

type Halokid struct {

    Header          string     

    Service        string     

    Method          string     

    Payload        []byte     

}

通信方式

HTTP2, 关于 http2 的特性请自行 research

服务端

常规来说 HTTP2 需要使用 TLS,需要生成证书,但是 go 有一个不需要 TLS 就可以使用 HTTP2 的实现,它就是 H2C,它是一个基于 TCP 之上构建的 HTTP2,拥有 http2 的一切特性,但是数据不加密,缺乏安全保证,我们服务端就采用 H2C 来实现

PS

https,基于 TLS 之上构建的 HTTP2

h2c,直接在 TCP 之上构建的 HTTP/2, 协议也是用 http

func main() {

  s := server.NewServer()

  s.RegisterSvc("Echo", new(service.Echo))

  log.Printf("s -------------- %+v", s)

  s.Run(":9527")

}

客户端

默认用浏览器(postman) 之类的来请求服务端,目前只支持 TLS 之上的 HTTP2(即 https),所以这个 RPC 服务端如果用浏览器来请求,会退为 HTTP1。直接用代码的 client 来请求,协议才是 HTTP2。

用 client 代码来请求,返回数据如下:

&{Status:200 OK StatusCode:200 Proto:HTTP/2.0 ProtoMajor:2 ProtoMinor:0 Header:map[Content-Length:[19] Content-Type:[text/plain; charset=utf-8] Date:[Sat, 30 Jan 2021 12:30:43 GMT]] Body:{cs:0xc0000ecdc0} ContentLength:19 TransferEncoding:[] Close:false Uncompressed:false Trailer:map[] Request:0xc000104000 TLS:}

func main() {

  client := http.Client{

    Transport:    &http2.Transport{

      AllowHTTP:  true,

      DialTLS: func(network, addr string, cfg *tls.Config) (conn net.Conn, err error) {

        return net.Dial(network, addr)

      },

    },

  }

  url := "http://127.0.0.1:9527"

  payload, err := json.Marshal(map[string]string {

    "name": "halokid",

  })

  ColorfulRabbit.CheckError(err, "客户端序列化payload请求错误")

  req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))

  req.Header.Add("svc", "Echo")

  req.Header.Add("method", "Say")

  rsp, _ := client.Do(req)

  log.Printf("RPC请求返回 --------- %+v", rsp)

  defer rsp.Body.Close()

  reply, _ := ioutil.ReadAll(rsp.Body)

  log.Printf("RPC请求返回reply --------- %+v", string(reply))

}

服务调用流程

本文链接:https://www.pangulab.com/post/kb-yo8n7r.html, 参与评论 »

--EOF--

你可能感兴趣的:(9 人团本之基于 HTTP2 搬一个 RPC 的砖 | 水木双)