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

     1  package client
     2  
     3  import (
     4  	"github.com/nyan233/littlerpc/core/common/errorhandler"
     5  	"github.com/nyan233/littlerpc/core/common/msgparser"
     6  	"github.com/nyan233/littlerpc/core/common/transport"
     7  	"github.com/nyan233/littlerpc/core/protocol/message"
     8  	"io"
     9  	"math"
    10  )
    11  
    12  func (c *Client) onRead(conn transport.ConnAdapter) {
    13  	c.parseMessageAndHandle(conn, nil, false)
    14  }
    15  
    16  func (c *Client) onMessage(conn transport.ConnAdapter, bytes []byte) {
    17  	c.parseMessageAndHandle(conn, bytes, true)
    18  }
    19  
    20  func (c *Client) parseMessageAndHandle(conn transport.ConnAdapter, data []byte, prepared bool) {
    21  	desc, ok := c.connSourceSet.LoadOk(conn)
    22  	if !ok {
    23  		c.logger.Error("LRPC: OnMessage lookup conn failed")
    24  		err := conn.Close()
    25  		if err != nil {
    26  			c.logger.Error("LRPC: close conn failed: %v", err)
    27  		}
    28  		return
    29  	}
    30  	var allMsg []msgparser.ParserMessage
    31  	var err error
    32  	if prepared {
    33  		allMsg, err = desc.parser.Parse(data)
    34  	} else {
    35  		allMsg, err = desc.parser.ParseOnReader(msgparser.DefaultReader(conn))
    36  	}
    37  	if err != nil {
    38  		c.logger.Error("LRPC: parse message failed: %v", err)
    39  		err := conn.Close()
    40  		if err != nil {
    41  			c.logger.Error("LRPC: close conn failed: %v", err)
    42  		}
    43  		return
    44  	}
    45  	if allMsg == nil || len(allMsg) <= 0 {
    46  		return
    47  	}
    48  	for _, pMsg := range allMsg {
    49  		// 单个连接返回最大能分配的Message Id代表遇到了服务端解析器解析失败的错误
    50  		// 这种情况下, 服务端没办法知道真正的Message Id, 如果不通知在这个连接上等待的回复调用者
    51  		// 的话就会导致对应调用被永远阻塞, 要是直接关闭连接的话就会导致无法知道真正出现的问题, 所以通知完
    52  		// 所有的调用者之后再关闭连接
    53  		if pMsg.Message.GetMsgId() == math.MaxUint64 {
    54  			oldNotify := desc.SwapNotifyChannel(nil)
    55  			if oldNotify == nil {
    56  				c.logger.Warn("LRPC: in onMessage time trigger onClose or parse error")
    57  				return
    58  			}
    59  			pErr := c.handleReturnError(pMsg.Message)
    60  			// 没有任何接收者则打印错误, 避免错误被忽略
    61  			if len(oldNotify) == 0 {
    62  				c.logger.Warn("LRPC: error not receiver : %v", pErr)
    63  			}
    64  			for _, channel := range oldNotify {
    65  				if pErr == nil {
    66  					pErr = c.eHandle.LWarpErrorDesc(errorhandler.ErrServer, "server parser error time return invalid response")
    67  				}
    68  				select {
    69  				case channel <- Complete{Error: pErr}:
    70  				default:
    71  					c.logger.Warn("LRPC: server parser parse message failed, but client notifySet channel is block")
    72  				}
    73  			}
    74  			_ = desc.ConnAdapter.Close()
    75  			return
    76  		}
    77  		switch pMsg.Message.GetMsgType() {
    78  		case message.ContextCancel:
    79  			// context cancel消息暂时不通知, 因为用的MsgId跟当前的Caller获得的MsgId一致
    80  			// 这样会导致后续消息找不到通知通道,
    81  			continue
    82  		case message.Return:
    83  			msgId := pMsg.Message.GetMsgId()
    84  			end, err := desc.PushCompleteMessage(msgId, Complete{
    85  				Message: pMsg.Message,
    86  			})
    87  			if err != nil {
    88  				c.logger.Warn(err.Error())
    89  				continue
    90  			}
    91  			if end && desc.isHalfClosed() {
    92  				c.logger.Debug("LRPC: soft close complete, all msg already completed : %v", desc.ConnAdapter.Close())
    93  			}
    94  		case message.Pong:
    95  			// TODO: keep-alive重置连接定时器
    96  		default:
    97  			c.logger.Warn("LRPC: unknown message type")
    98  		}
    99  	}
   100  }
   101  
   102  func (c *Client) onOpen(conn transport.ConnAdapter) {
   103  	// 2023/03/14 - 新的负载均衡器设计使得connSource不需要在OnOpen()中初始化
   104  	return
   105  }
   106  
   107  func (c *Client) onClose(conn transport.ConnAdapter, err error) {
   108  	desc, ok := c.connSourceSet.LoadOk(conn)
   109  	if !ok {
   110  		c.logger.Error("LRPC: OnClose lookup conn failed")
   111  		return
   112  	}
   113  	oldNotify := desc.SwapNotifyChannel(nil)
   114  	if oldNotify == nil {
   115  		c.logger.Warn("LRPC: onMessage click parse error")
   116  	} else {
   117  		for _, channel := range oldNotify {
   118  			channel <- Complete{
   119  				Error: c.eHandle.LWarpErrorDesc(errorhandler.ErrConnection, "client receive onClose"),
   120  			}
   121  		}
   122  	}
   123  	if err != nil && err != io.EOF {
   124  		c.logger.Error("LRPC: OnClose err : %v", err)
   125  	}
   126  }