Ai
0 Star 1 Fork 0

zoe/demo
关闭

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
http2rpc.go 3.49 KB
一键复制 编辑 原始数据 按行查看 历史
zoe 提交于 2018-05-16 13:47 +08:00 . 通过断言代替反射调用公共方法
package http2rpc
import (
"context"
"io/ioutil"
"log"
"net/http"
"time"
"gitee.com/zzoe/demo/client/web/backend/clientpool"
"gitee.com/zzoe/demo/client/web/backend/srvdefine"
"gitee.com/zzoe/demo/message/pubmsg"
"github.com/smallnest/rpcx/codec"
"github.com/smallnest/rpcx/share"
)
const (
//XServicePath service path
XServicePath = "X-RPCX-ServicePath"
//XServiceMethod service method
XServiceMethod = "X-RPCX-ServiceMethod"
)
//HTTP2RPC http to rpc handler
type HTTP2RPC struct {
HTTPCodec codec.Codec
}
//ServeHTTP 将http请求转为rpc
func (handler *HTTP2RPC) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//从Cookie中取sessionid
reqSessionID := ""
if reqSessionIDCookie, _ := r.Cookie("sessionid"); reqSessionIDCookie != nil {
reqSessionID = reqSessionIDCookie.Value
log.Println("reqSessionID:", reqSessionID)
}
//http请求转换为rpc请求
rh := r.Header
sp := rh.Get(XServicePath)
sm := rh.Get(XServiceMethod)
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Println("ioutil.ReadAll failed!")
response(w, r, nil, err)
return
}
log.Println("request:", string(reqBody))
//map的并发读是没有问题的!
args, err := srvdefine.ServiceMethodParamPool.Get(sp, sm, srvdefine.ParamArgs)
if err != nil {
log.Printf("srvdefine.SrvVarPool.Get(%s, %s, %v) failed!", sp, sm, srvdefine.ParamArgs)
response(w, r, nil, err)
return
}
reply, err := srvdefine.ServiceMethodParamPool.Get(sp, sm, srvdefine.ParamReply)
if err != nil {
log.Printf("srvdefine.SrvVarPool.Get(%s, %s, %v) failed!", sp, sm, srvdefine.ParamReply)
response(w, r, nil, err)
return
}
//根据渠道的SerialType解码请求
if err := handler.HTTPCodec.Decode(reqBody, args); err != nil {
log.Println("handler.HTTPCodec.Decode failed!")
response(w, r, nil, err)
return
}
log.Printf("args:%+v\n", args)
// 取xClient
xClient, err := clientpool.GetXClient(sp)
if err != nil {
log.Println("clientpool.GetXClient failed!")
response(w, r, nil, err)
return
}
//session校验数据赋值
xClient.Auth(reqSessionID)
ctx := context.WithValue(context.Background(), share.ReqMetaDataKey, make(map[string]string))
// 开始远程调用
if err := xClient.Call(ctx, sm, args, reply); err != nil {
log.Printf("failed to call: %v, %+v, %+v\n", sm, args, reply)
response(w, r, nil, err)
return
}
log.Printf("reply:%+v\n", reply)
srvdefine.ServiceMethodParamPool.Put(sp, sm, srvdefine.ParamArgs, args)
//设置Cookie
resSessionID := reply.(pubmsg.PublicReply).GetSessionID()
// resSeesionIDValue := reflect.ValueOf(reply).MethodByName("GetSessionID").Call(nil)[0]
// resSessionID := resSeesionIDValue.String()
log.Println("resSessionID:", resSessionID)
if resSessionID != "" {
cookie := &http.Cookie{
Name: "sessionid",
Value: resSessionID,
Expires: time.Now().Add(time.Hour),
}
http.SetCookie(w, cookie)
}
//根据渠道的SerialType编码请求
resBody, err := handler.HTTPCodec.Encode(reply)
if err != nil {
log.Println("handler.HTTPCodec.Encode failed!")
response(w, r, nil, err)
}
srvdefine.ServiceMethodParamPool.Put(sp, sm, srvdefine.ParamReply, reply)
// 响应http请求
response(w, r, resBody, nil)
}
func response(w http.ResponseWriter, r *http.Request, resByte []byte, err error) {
if err != nil {
log.Println(err)
http.NotFound(w, r)
return
}
log.Println("Response:", string(resByte))
w.Write(resByte)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/zzoe/demo.git
git@gitee.com:zzoe/demo.git
zzoe
demo
demo
v1.0.4

搜索帮助