dubbo.apache.org/dubbo-go/v3@v3.1.1/remoting/getty/readwriter.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package getty 19 20 import ( 21 "reflect" 22 ) 23 24 import ( 25 getty "github.com/apache/dubbo-getty" 26 27 "github.com/dubbogo/gost/log/logger" 28 29 perrors "github.com/pkg/errors" 30 ) 31 32 import ( 33 "dubbo.apache.org/dubbo-go/v3/protocol/dubbo/impl" 34 "dubbo.apache.org/dubbo-go/v3/remoting" 35 ) 36 37 // RpcClientPackageHandler Read data from server and Write data to server 38 type RpcClientPackageHandler struct { 39 client *Client 40 } 41 42 // NewRpcClientPackageHandler create a RpcClientPackageHandler 43 func NewRpcClientPackageHandler(client *Client) *RpcClientPackageHandler { 44 return &RpcClientPackageHandler{client: client} 45 } 46 47 // Read data from server. if the package size from server is larger than 4096 byte, server will read 4096 byte 48 // and send to client each time. the Read can assemble it. 49 func (p *RpcClientPackageHandler) Read(ss getty.Session, data []byte) (interface{}, int, error) { 50 rsp, length, err := (p.client.codec).Decode(data) 51 if err != nil { 52 err = perrors.WithStack(err) 53 } 54 if rsp == ((*remoting.DecodeResult)(nil)) { 55 return nil, length, err 56 } 57 if rsp.Result == ((*remoting.Response)(nil)) || rsp.Result == ((*remoting.Request)(nil)) { 58 return nil, length, err 59 } 60 return rsp, length, err 61 } 62 63 // Write send the data to server 64 func (p *RpcClientPackageHandler) Write(ss getty.Session, pkg interface{}) ([]byte, error) { 65 req, ok := pkg.(*remoting.Request) 66 maxBufLength := clientConf.GettySessionParam.MaxMsgLen + impl.HEADER_LENGTH 67 if ok { 68 buf, err := (p.client.codec).EncodeRequest(req) 69 bufLength := buf.Len() 70 if bufLength > maxBufLength { 71 logger.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, clientConf.GettySessionParam.MaxMsgLen) 72 return nil, perrors.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, clientConf.GettySessionParam.MaxMsgLen) 73 } 74 if err != nil { 75 logger.Warnf("binary.Write(req{%#v}) = err{%#v}", req, perrors.WithStack(err)) 76 return nil, perrors.WithStack(err) 77 } 78 return buf.Bytes(), nil 79 } 80 81 res, ok := pkg.(*remoting.Response) 82 if ok { 83 buf, err := (p.client.codec).EncodeResponse(res) 84 bufLength := buf.Len() 85 if bufLength > maxBufLength { 86 logger.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, clientConf.GettySessionParam.MaxMsgLen) 87 return nil, perrors.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, clientConf.GettySessionParam.MaxMsgLen) 88 } 89 if err != nil { 90 logger.Warnf("binary.Write(res{%#v}) = err{%#v}", req, perrors.WithStack(err)) 91 return nil, perrors.WithStack(err) 92 } 93 return buf.Bytes(), nil 94 } 95 96 logger.Errorf("illegal pkg:%+v\n", pkg) 97 return nil, perrors.New("invalid rpc request") 98 } 99 100 // RpcServerPackageHandler Read data from client and Write data to client 101 type RpcServerPackageHandler struct { 102 server *Server 103 } 104 105 func NewRpcServerPackageHandler(server *Server) *RpcServerPackageHandler { 106 return &RpcServerPackageHandler{server: server} 107 } 108 109 // Read data from client. if the package size from client is larger than 4096 byte, client will read 4096 byte 110 // and send to client each time. the Read can assemble it. 111 func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface{}, int, error) { 112 req, length, err := (p.server.codec).Decode(data) 113 if err != nil { 114 err = perrors.WithStack(err) 115 } 116 if req == ((*remoting.DecodeResult)(nil)) { 117 return nil, length, err 118 } 119 if req.Result == ((*remoting.Request)(nil)) || req.Result == ((*remoting.Response)(nil)) { 120 return nil, length, err // as getty rule 121 } 122 return req, length, err 123 } 124 125 // Write send the data to client 126 func (p *RpcServerPackageHandler) Write(ss getty.Session, pkg interface{}) ([]byte, error) { 127 res, ok := pkg.(*remoting.Response) 128 maxBufLength := srvConf.GettySessionParam.MaxMsgLen + impl.HEADER_LENGTH 129 if ok { 130 buf, err := (p.server.codec).EncodeResponse(res) 131 bufLength := buf.Len() 132 if bufLength > maxBufLength { 133 logger.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, srvConf.GettySessionParam.MaxMsgLen) 134 return nil, perrors.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, srvConf.GettySessionParam.MaxMsgLen) 135 } 136 if err != nil { 137 logger.Warnf("binary.Write(res{%#v}) = err{%#v}", res, perrors.WithStack(err)) 138 return nil, perrors.WithStack(err) 139 } 140 return buf.Bytes(), nil 141 } 142 143 req, ok := pkg.(*remoting.Request) 144 if ok { 145 buf, err := (p.server.codec).EncodeRequest(req) 146 bufLength := buf.Len() 147 if bufLength > maxBufLength { 148 logger.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, srvConf.GettySessionParam.MaxMsgLen) 149 return nil, perrors.Errorf("Data length %d too large, max payload %d", bufLength-impl.HEADER_LENGTH, srvConf.GettySessionParam.MaxMsgLen) 150 } 151 if err != nil { 152 logger.Warnf("binary.Write(req{%#v}) = err{%#v}", res, perrors.WithStack(err)) 153 return nil, perrors.WithStack(err) 154 } 155 return buf.Bytes(), nil 156 } 157 158 logger.Errorf("illegal pkg:%+v\n, it is %+v", pkg, reflect.TypeOf(pkg)) 159 return nil, perrors.New("invalid rpc response") 160 }