github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/server/server_handle.go (about)

     1  package server
     2  
     3  import (
     4  	"github.com/nyan233/littlerpc/core/common/msgwriter"
     5  	"github.com/nyan233/littlerpc/core/common/transport"
     6  	"github.com/nyan233/littlerpc/core/common/utils/debug"
     7  	"github.com/nyan233/littlerpc/core/middle/packer"
     8  	error2 "github.com/nyan233/littlerpc/core/protocol/error"
     9  	"github.com/nyan233/littlerpc/core/protocol/message"
    10  	"github.com/nyan233/littlerpc/core/utils/convert"
    11  	"strconv"
    12  )
    13  
    14  func (s *Server) encodeAndSendMsg(msgOpt *messageOpt, msg *message.Message, beforeErr error2.LErrorDesc, handleErr bool) {
    15  	if err := s.pManager.Send4S(msgOpt.PCtx, msg, beforeErr); err != nil {
    16  		s.handleError(msgOpt.Conn, msgOpt.Desc.Writer, msg.GetMsgId(), err)
    17  		return
    18  	}
    19  	if handleErr && beforeErr != nil {
    20  		s.handleError(msgOpt.Conn, msgOpt.Desc.Writer, msg.GetMsgId(), beforeErr)
    21  		return
    22  	}
    23  	err := msgOpt.Desc.Writer.Write(msgwriter.Argument{
    24  		Message: msg,
    25  		Conn:    msgOpt.Conn,
    26  		Encoder: msgOpt.Packer,
    27  		Pool:    s.pool.TakeBytesPool(),
    28  		OnDebug: debug.MessageDebug(s.logger, s.config.Load().Debug),
    29  		EHandle: s.eHandle,
    30  	}, msgOpt.Header)
    31  	_ = s.pManager.AfterSend4S(msgOpt.PCtx, msg, err)
    32  }
    33  
    34  // NOTE: 这里负责处理Server遇到的所有错误, 它会在遇到严重的错误时关闭连接, 不那么重要的错误则尝试返回给客户端
    35  // NOTE: 严重错误 -> UnsafeOption | MessageDecodingFailed | MessageEncodingFailed
    36  // NOTE: 轻微错误 -> 除了严重错误都是
    37  // Update: LittleRpc现在的错误返回统一使用NoMux类型的消息
    38  // writer == nil时从msgwriter选择一个Writer, 默认选择NoMux Write
    39  func (s *Server) handleError(conn transport.ConnAdapter, writer msgwriter.Writer, msgId uint64, errNo error2.LErrorDesc) {
    40  	bytesBuffer := s.pool.TakeBytesPool()
    41  	cfg := s.config.Load()
    42  	if writer == nil {
    43  		writer = cfg.WriterFactory()
    44  	}
    45  	// 普通错误打印警告, 严重错误打印error
    46  	switch errNo.Code() {
    47  	case error2.UnsafeOption, error2.MessageDecodingFailed,
    48  		error2.MessageEncodingFailed, error2.ConnectionErr:
    49  		s.logger.Error("LRPC: trigger must close connection error: %v", errNo)
    50  	default:
    51  		s.logger.Warn("LRPC: trigger connection error: %v", errNo)
    52  	}
    53  	msg := message.New()
    54  	msg.SetMsgType(message.Return)
    55  	msg.SetMsgId(msgId)
    56  	msg.MetaData.Store(message.ErrorCode, strconv.Itoa(errNo.Code()))
    57  	msg.MetaData.Store(message.ErrorMessage, errNo.Message())
    58  	// 为空则不序列化Mores, 否则会造成空间浪费
    59  	mores := errNo.Mores()
    60  	if mores != nil && len(mores) > 0 {
    61  		bytes, err := errNo.MarshalMores()
    62  		if err != nil {
    63  			s.logger.Error("LRPC: handleError marshal error mores failed: %v", err)
    64  			_ = conn.Close()
    65  			return
    66  		} else {
    67  			msg.MetaData.Store(message.ErrorMore, convert.BytesToString(bytes))
    68  		}
    69  	}
    70  	err := writer.Write(msgwriter.Argument{
    71  		Message:    msg,
    72  		Conn:       conn,
    73  		Encoder:    packer.Get("text"),
    74  		Pool:       bytesBuffer,
    75  		OnDebug:    debug.MessageDebug(s.logger, cfg.Debug),
    76  		OnComplete: nil, //TODO: 将某个合适的插件注入
    77  		EHandle:    s.eHandle,
    78  	}, message.MagicNumber)
    79  	if err != nil {
    80  		s.logger.Error("LRPC: handleError write bytes error: %v", err)
    81  	}
    82  }