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.
 
 

110 lines
2.6 KiB

package server
import (
"context"
"github.com/gorilla/websocket"
"runtime/debug"
"sonet/internal/gateway_ws/session"
"sonet/pkg/grpc/generic"
"sonet/pkg/protocol"
"sonet/pkg/utils/logger"
)
type ConnHandler struct {
grpcFactory *generic.GrpcGenericClientFactory
}
func NewConnHandler(grpcFactory *generic.GrpcGenericClientFactory) *ConnHandler {
return &ConnHandler{
grpcFactory: grpcFactory,
}
}
func (c *ConnHandler) handleConn(conn *websocket.Conn) {
client := session.NewNetClient(conn, ReadDeadline, WriteDeadline)
defer func() {
// TODO 连接关闭,mq发送关闭事件
// 捕获其他错误
if r := recover(); r != nil {
logger.Error("NetClient recover error: ", r)
// 输出堆栈信息
logger.Error("NetClient recover error stack: ", string(debug.Stack()))
}
}()
defer client.Close()
for {
ignore, message, err := client.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
logger.Error("unexpected close error: ", err)
} else {
// 读失败
logger.Errorf("NetClient ReadMessage error: %T, %v", err, err)
}
return
}
if ignore {
continue
}
payload, err := protocol.DecodeSo(message)
if err != nil {
logger.Errorf("decode message error: len=%d", len(message), err)
return
}
header := payload.Header
// grpc generic call
ctx := context.Background()
grpcClient, err := c.grpcFactory.GetClient(ctx, header.Svc)
if err != nil {
logger.Error("get grpc generic client error: ", err)
continue
}
resp, err := grpcClient.InvokeUnary(ctx, header.Target, payload.Body)
if err != nil {
// todo 提取 err: fmt.Sprintf("rpc error: code = %s desc = %s", s.Code(), s.Message())
writeError(client, header.SeqId, err.Error())
logger.Error("grpc generic call error: ", err)
continue
}
// write response
header.Type = protocol.TypeResponse
header.Target = resp.XXX_MessageName()
payload.Body, err = resp.Marshal()
if err != nil {
logger.Error("generic call response marshal error: ", err)
continue
}
resMessage, err := protocol.EncodeSo(payload)
if err != nil {
logger.Error("grpc generic call error: ", err)
continue
}
client.MustWrite(resMessage)
}
}
func writeError(client *session.NetClient, seqId int32, errMsg string) {
header := &protocol.Header{}
payload := &protocol.Payload{Header: header}
header.Magic = protocol.Magic
header.Type = protocol.TypeError
header.Status = 50
header.SeqId = seqId
payload.Body = []byte(errMsg)
message, err := protocol.EncodeSo(payload)
if err != nil {
logger.Error("NetClient writeError encode error:", err)
return
}
client.MustWrite(message)
return
}