You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Open-IM-Server/internal/api2rpc/rpc.go

115 lines
2.7 KiB

2 years ago
package api2rpc
import (
"context"
"google.golang.org/grpc"
2 years ago
"reflect"
2 years ago
)
2 years ago
var nameMap = map[string]string{}
func getName[T any]() string {
var t T
return reflect.TypeOf(&t).Elem().Name()
}
2 years ago
// NewRpc A: apiReq B: apiResp C: rpcReq D: rpcResp Z: rpcClient (group.GroupClient)
2 years ago
func NewRpc[A, B any, C, D any, Z any](bind ApiBind[A, B], client func(conn *grpc.ClientConn) Z, rpc func(client Z, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)) *RpcXXXX[A, B, C, D, Z] {
return &RpcXXXX[A, B, C, D, Z]{
2 years ago
bind: bind,
client: client,
rpc: rpc,
}
}
2 years ago
type RpcXXXX[A, B any, C, D any, Z any] struct {
2 years ago
bind ApiBind[A, B]
name string
client func(conn *grpc.ClientConn) Z
rpc func(client Z, ctx context.Context, req *C, options ...grpc.CallOption) (*D, error)
before func(apiReq *A, rpcReq *C, bind func() error) error
after func(rpcResp *D, apiResp *B, bind func() error) error
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) Name(name string) *RpcXXXX[A, B, C, D, Z] {
2 years ago
a.name = name
return a
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) Before(fn func(apiReq *A, rpcReq *C, bind func() error) error) *RpcXXXX[A, B, C, D, Z] {
2 years ago
a.before = fn
return a
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) After(fn func(rpcResp *D, apiResp *B, bind func() error) error) *RpcXXXX[A, B, C, D, Z] {
2 years ago
a.after = fn
return a
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) defaultCopyReq(apiReq *A, rpcReq *C) error {
2 years ago
CopyAny(apiReq, rpcReq)
return nil
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) defaultCopyResp(rpcResp *D, apiResp *B) error {
2 years ago
CopyAny(rpcResp, apiResp)
return nil
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) getZtype() string {
return ""
}
func (a *RpcXXXX[A, B, C, D, Z]) GetGrpcConn() (*grpc.ClientConn, error) {
if a.name == "" {
a.name = nameMap[getName[Z]()]
}
// todo 获取连接
2 years ago
return nil, nil // todo
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) execute() (*B, error) {
2 years ago
var apiReq A
if err := a.bind.Bind(&apiReq); err != nil {
return nil, err
}
opID := a.bind.OperationID()
userID, err := a.bind.OpUserID()
if err != nil {
return nil, err
}
_, _ = opID, userID
var rpcReq C
if a.before == nil {
err = a.defaultCopyReq(&apiReq, &rpcReq)
} else {
err = a.before(&apiReq, &rpcReq, func() error { return a.defaultCopyReq(&apiReq, &rpcReq) })
}
if err != nil {
return nil, err
}
conn, err := a.GetGrpcConn()
if err != nil {
return nil, err
}
rpcResp, err := a.rpc(a.client(conn), a.bind.Context(), &rpcReq)
if err != nil {
return nil, err
}
var apiResp B
if a.after == nil {
err = a.defaultCopyResp(rpcResp, &apiResp)
} else {
err = a.after(rpcResp, &apiResp, func() error { return a.defaultCopyResp(rpcResp, &apiResp) })
}
if err != nil {
return nil, err
}
return &apiResp, nil
}
2 years ago
func (a *RpcXXXX[A, B, C, D, Z]) Call() {
2 years ago
a.bind.Resp(a.execute())
}