in response.go [67:148]
func packResponse(header DubboHeader, ret interface{}) ([]byte, error) {
var byteArray []byte
response := EnsureResponse(ret)
hb := header.Type == PackageHeartbeat
// magic
if hb {
byteArray = append(byteArray, DubboResponseHeartbeatHeader[:]...)
} else {
byteArray = append(byteArray, DubboResponseHeaderBytes[:]...)
}
// set serialID, identify serialization types, eg: fastjson->6, hessian2->2
byteArray[2] |= header.SerialID & SERIAL_MASK
// response status
if header.ResponseStatus != 0 {
byteArray[3] = header.ResponseStatus
}
// request id
binary.BigEndian.PutUint64(byteArray[4:], uint64(header.ID))
// body
encoder := NewEncoder()
encoder.Append(byteArray[:HEADER_LENGTH])
if header.ResponseStatus == Response_OK {
if hb {
encoder.Encode(nil)
} else {
atta := isSupportResponseAttachment(response.Attachments[DUBBO_VERSION_KEY])
var resWithException, resValue, resNullValue int32
if atta {
resWithException = RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS
resValue = RESPONSE_VALUE_WITH_ATTACHMENTS
resNullValue = RESPONSE_NULL_VALUE_WITH_ATTACHMENTS
} else {
resWithException = RESPONSE_WITH_EXCEPTION
resValue = RESPONSE_VALUE
resNullValue = RESPONSE_NULL_VALUE
}
if response.Exception != nil { // throw error
encoder.Encode(resWithException)
if t, ok := response.Exception.(java_exception.Throwabler); ok {
encoder.Encode(t)
} else {
encoder.Encode(java_exception.NewThrowable(response.Exception.Error()))
}
} else {
if response.RspObj == nil {
encoder.Encode(resNullValue)
} else {
encoder.Encode(resValue)
encoder.Encode(response.RspObj) // result
}
}
if atta {
encoder.Encode(response.Attachments) // attachments
}
}
} else {
if response.Exception != nil { // throw error
encoder.Encode(response.Exception.Error())
} else {
encoder.Encode(response.RspObj)
}
}
byteArray = encoder.Buffer()
byteArray = EncNull(byteArray) // if not, "java client" will throw exception "unexpected end of file"
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
}