in request.go [183:268]
func packRequest(service Service, header DubboHeader, req interface{}) ([]byte, error) {
var (
err error
types string
byteArray []byte
pkgLen int
)
request := EnsureRequest(req)
args, ok := request.Params.([]interface{})
if !ok {
return nil, perrors.Errorf("@params is not of type: []interface{}")
}
hb := header.Type == PackageHeartbeat
//////////////////////////////////////////
// byteArray
//////////////////////////////////////////
// magic
switch header.Type {
case PackageHeartbeat:
byteArray = append(byteArray, DubboRequestHeartbeatHeader[:]...)
case PackageRequest_TwoWay:
byteArray = append(byteArray, DubboRequestHeaderBytesTwoWay[:]...)
default:
byteArray = append(byteArray, DubboRequestHeaderBytes[:]...)
}
// serialization id, two way flag, event, request/response flag
// SerialID is id of serialization approach in java dubbo
byteArray[2] |= header.SerialID & SERIAL_MASK
// request id
binary.BigEndian.PutUint64(byteArray[4:], uint64(header.ID))
encoder := NewEncoder()
encoder.Append(byteArray[:HEADER_LENGTH])
//////////////////////////////////////////
// body
//////////////////////////////////////////
if hb {
encoder.Encode(nil)
goto END
}
// dubbo version + path + version + method
encoder.Encode(DEFAULT_DUBBO_PROTOCOL_VERSION)
encoder.Encode(service.Path)
encoder.Encode(service.Version)
encoder.Encode(service.Method)
// args = args type list + args value list
if types, err = getArgsTypeList(args); err != nil {
return nil, perrors.Wrapf(err, " PackRequest(args:%+v)", args)
}
encoder.Encode(types)
for _, v := range args {
encoder.Encode(v)
}
request.Attachments[PATH_KEY] = service.Path
request.Attachments[VERSION_KEY] = service.Version
if len(service.Group) > 0 {
request.Attachments[GROUP_KEY] = service.Group
}
if len(service.Interface) > 0 {
request.Attachments[INTERFACE_KEY] = service.Interface
}
if service.Timeout != 0 {
request.Attachments[TIMEOUT_KEY] = strconv.Itoa(int(service.Timeout / time.Millisecond))
}
encoder.Encode(request.Attachments)
END:
byteArray = encoder.Buffer()
pkgLen = len(byteArray)
if pkgLen > int(DEFAULT_LEN) { // 8M
return nil, perrors.Errorf("Data length %d too large, max payload %d", pkgLen, DEFAULT_LEN)
}
// byteArray{body length}
binary.BigEndian.PutUint32(byteArray[12:], uint32(pkgLen-HEADER_LENGTH))
return byteArray, nil
}