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  }