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 }