diff --git a/protocol/dubbo/client.go b/protocol/dubbo/client.go
deleted file mode 100644
index 630e9a76862d7d5f9be6caeb6a678936f940ac40..0000000000000000000000000000000000000000
--- a/protocol/dubbo/client.go
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"math/rand"
-//	"strings"
-//	"sync"
-//	"time"
-//)
-//
-//import (
-//	hessian "github.com/apache/dubbo-go-hessian2"
-//	"github.com/dubbogo/getty"
-//	gxsync "github.com/dubbogo/gost/sync"
-//	perrors "github.com/pkg/errors"
-//	"go.uber.org/atomic"
-//	"gopkg.in/yaml.v2"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/constant"
-//	"github.com/apache/dubbo-go/common/logger"
-//	"github.com/apache/dubbo-go/config"
-//)
-//
-//var (
-//	errInvalidCodecType  = perrors.New("illegal CodecType")
-//	errInvalidAddress    = perrors.New("remote address invalid or empty")
-//	errSessionNotExist   = perrors.New("session not exist")
-//	errClientClosed      = perrors.New("client closed")
-//	errClientReadTimeout = perrors.New("client read timeout")
-//
-//	clientConf   *ClientConfig
-//	clientGrpool *gxsync.TaskPool
-//)
-//
-//func init() {
-//
-//	// load clientconfig from consumer_config
-//	// default use dubbo
-//	consumerConfig := config.GetConsumerConfig()
-//	if consumerConfig.ApplicationConfig == nil {
-//		return
-//	}
-//	protocolConf := config.GetConsumerConfig().ProtocolConf
-//	defaultClientConfig := GetDefaultClientConfig()
-//	if protocolConf == nil {
-//		logger.Info("protocol_conf default use dubbo config")
-//	} else {
-//		dubboConf := protocolConf.(map[interface{}]interface{})[DUBBO]
-//		if dubboConf == nil {
-//			logger.Warnf("dubboConf is nil")
-//			return
-//		}
-//		dubboConfByte, err := yaml.Marshal(dubboConf)
-//		if err != nil {
-//			panic(err)
-//		}
-//		err = yaml.Unmarshal(dubboConfByte, &defaultClientConfig)
-//		if err != nil {
-//			panic(err)
-//		}
-//	}
-//	clientConf = &defaultClientConfig
-//	if err := clientConf.CheckValidity(); err != nil {
-//		logger.Warnf("[CheckValidity] error: %v", err)
-//		return
-//	}
-//	setClientGrpool()
-//
-//	rand.Seed(time.Now().UnixNano())
-//}
-//
-//// SetClientConf ...
-//func SetClientConf(c ClientConfig) {
-//	clientConf = &c
-//	err := clientConf.CheckValidity()
-//	if err != nil {
-//		logger.Warnf("[ClientConfig CheckValidity] error: %v", err)
-//		return
-//	}
-//	setClientGrpool()
-//}
-//
-//// GetClientConf ...
-//func GetClientConf() ClientConfig {
-//	return *clientConf
-//}
-//
-//func setClientGrpool() {
-//	if clientConf.GrPoolSize > 1 {
-//		clientGrpool = gxsync.NewTaskPool(gxsync.WithTaskPoolTaskPoolSize(clientConf.GrPoolSize), gxsync.WithTaskPoolTaskQueueLength(clientConf.QueueLen),
-//			gxsync.WithTaskPoolTaskQueueNumber(clientConf.QueueNumber))
-//	}
-//}
-//
-//// Options ...
-//type Options struct {
-//	// connect timeout
-//	ConnectTimeout time.Duration
-//	// request timeout
-//	RequestTimeout time.Duration
-//}
-//
-////AsyncCallbackResponse async response for dubbo
-//type AsyncCallbackResponse struct {
-//	common.CallbackResponse
-//	Opts      Options
-//	Cause     error
-//	Start     time.Time // invoke(call) start time == write start time
-//	ReadStart time.Time // read start time, write duration = ReadStart - Start
-//	Reply     interface{}
-//}
-//
-//// Client ...
-//type Client struct {
-//	opts     Options
-//	conf     ClientConfig
-//	pool     *gettyRPCClientPool
-//	sequence atomic.Uint64
-//
-//	pendingResponses *sync.Map
-//}
-//
-//// NewClient ...
-//func NewClient(opt Options) *Client {
-//
-//	switch {
-//	case opt.ConnectTimeout == 0:
-//		opt.ConnectTimeout = 3 * time.Second
-//		fallthrough
-//	case opt.RequestTimeout == 0:
-//		opt.RequestTimeout = 3 * time.Second
-//	}
-//
-//	// make sure that client request sequence is an odd number
-//	initSequence := uint64(rand.Int63n(time.Now().UnixNano()))
-//	if initSequence%2 == 0 {
-//		initSequence++
-//	}
-//
-//	c := &Client{
-//		opts:             opt,
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//	}
-//	c.sequence.Store(initSequence)
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	return c
-//}
-//
-//// Request ...
-//type Request struct {
-//	addr   string
-//	svcUrl common.URL
-//	method string
-//	args   interface{}
-//	atta   map[string]string
-//}
-//
-//// NewRequest ...
-//func NewRequest(addr string, svcUrl common.URL, method string, args interface{}, atta map[string]string) *Request {
-//	return &Request{
-//		addr:   addr,
-//		svcUrl: svcUrl,
-//		method: method,
-//		args:   args,
-//		atta:   atta,
-//	}
-//}
-//
-//// Response ...
-//type Response struct {
-//	reply interface{}
-//	atta  map[string]string
-//}
-//
-//// NewResponse ...
-//func NewResponse(reply interface{}, atta map[string]string) *Response {
-//	return &Response{
-//		reply: reply,
-//		atta:  atta,
-//	}
-//}
-//
-//// CallOneway call one way
-//func (c *Client) CallOneway(request *Request) error {
-//
-//	return perrors.WithStack(c.call(CT_OneWay, request, NewResponse(nil, nil), nil))
-//}
-//
-//// Call if @response is nil, the transport layer will get the response without notify the invoker.
-//func (c *Client) Call(request *Request, response *Response) error {
-//
-//	ct := CT_TwoWay
-//	if response.reply == nil {
-//		ct = CT_OneWay
-//	}
-//
-//	return perrors.WithStack(c.call(ct, request, response, nil))
-//}
-//
-//// AsyncCall ...
-//func (c *Client) AsyncCall(request *Request, callback common.AsyncCallback, response *Response) error {
-//
-//	return perrors.WithStack(c.call(CT_TwoWay, request, response, callback))
-//}
-//
-//func (c *Client) call(ct CallType, request *Request, response *Response, callback common.AsyncCallback) error {
-//
-//	p := &DubboPackage{}
-//	p.Service.Path = strings.TrimPrefix(request.svcUrl.Path, "/")
-//	p.Service.Interface = request.svcUrl.GetParam(constant.INTERFACE_KEY, "")
-//	p.Service.Version = request.svcUrl.GetParam(constant.VERSION_KEY, "")
-//	p.Service.Group = request.svcUrl.GetParam(constant.GROUP_KEY, "")
-//	p.Service.Method = request.method
-//
-//	p.Service.Timeout = c.opts.RequestTimeout
-//	var timeout = request.svcUrl.GetParam(strings.Join([]string{constant.METHOD_KEYS, request.method + constant.RETRIES_KEY}, "."), "")
-//	if len(timeout) != 0 {
-//		if t, err := time.ParseDuration(timeout); err == nil {
-//			p.Service.Timeout = t
-//		}
-//	}
-//
-//	p.Header.SerialID = byte(S_Dubbo)
-//	p.Body = hessian.NewRequest(request.args, request.atta)
-//
-//	var rsp *PendingResponse
-//	if ct != CT_OneWay {
-//		p.Header.Type = hessian.PackageRequest_TwoWay
-//		rsp = NewPendingResponse()
-//		rsp.response = response
-//		rsp.callback = callback
-//	} else {
-//		p.Header.Type = hessian.PackageRequest
-//	}
-//
-//	var (
-//		err     error
-//		session getty.Session
-//		conn    *gettyRPCClient
-//	)
-//	conn, session, err = c.selectSession(request.addr)
-//	if err != nil {
-//		return perrors.WithStack(err)
-//	}
-//	if session == nil {
-//		return errSessionNotExist
-//	}
-//	defer func() {
-//		if err == nil {
-//			c.pool.put(conn)
-//			return
-//		}
-//		conn.close()
-//	}()
-//
-//	if err = c.transfer(session, p, rsp); err != nil {
-//		return perrors.WithStack(err)
-//	}
-//
-//	if ct == CT_OneWay || callback != nil {
-//		return nil
-//	}
-//
-//	select {
-//	case <-getty.GetTimeWheel().After(c.opts.RequestTimeout):
-//		c.removePendingResponse(SequenceType(rsp.seq))
-//		return perrors.WithStack(errClientReadTimeout)
-//	case <-rsp.done:
-//		err = rsp.err
-//	}
-//
-//	return perrors.WithStack(err)
-//}
-//
-//// Close ...
-//func (c *Client) Close() {
-//	if c.pool != nil {
-//		c.pool.close()
-//	}
-//	c.pool = nil
-//}
-//
-//func (c *Client) selectSession(addr string) (*gettyRPCClient, getty.Session, error) {
-//	rpcClient, err := c.pool.getGettyRpcClient(DUBBO, addr)
-//	if err != nil {
-//		return nil, nil, perrors.WithStack(err)
-//	}
-//	return rpcClient, rpcClient.selectSession(), nil
-//}
-//
-//func (c *Client) heartbeat(session getty.Session) error {
-//	return c.transfer(session, nil, NewPendingResponse())
-//}
-//
-//func (c *Client) transfer(session getty.Session, pkg *DubboPackage,
-//	rsp *PendingResponse) error {
-//
-//	var (
-//		sequence uint64
-//		err      error
-//	)
-//
-//	sequence = c.sequence.Add(1)
-//
-//	if pkg == nil {
-//		pkg = &DubboPackage{}
-//		pkg.Body = hessian.NewRequest([]interface{}{}, nil)
-//		pkg.Body = []interface{}{}
-//		pkg.Header.Type = hessian.PackageHeartbeat
-//		pkg.Header.SerialID = byte(S_Dubbo)
-//	}
-//	pkg.Header.ID = int64(sequence)
-//
-//	// cond1
-//	if rsp != nil {
-//		rsp.seq = sequence
-//		c.addPendingResponse(rsp)
-//	}
-//
-//	err = session.WritePkg(pkg, c.opts.RequestTimeout)
-//	if err != nil {
-//		c.removePendingResponse(SequenceType(rsp.seq))
-//	} else if rsp != nil { // cond2
-//		// cond2 should not merged with cond1. cause the response package may be returned very
-//		// soon and it will be handled by other goroutine.
-//		rsp.readStart = time.Now()
-//	}
-//
-//	return perrors.WithStack(err)
-//}
-//
-//func (c *Client) addPendingResponse(pr *PendingResponse) {
-//	c.pendingResponses.Store(SequenceType(pr.seq), pr)
-//}
-//
-//func (c *Client) removePendingResponse(seq SequenceType) *PendingResponse {
-//	if c.pendingResponses == nil {
-//		return nil
-//	}
-//	if presp, ok := c.pendingResponses.Load(seq); ok {
-//		c.pendingResponses.Delete(seq)
-//		return presp.(*PendingResponse)
-//	}
-//	return nil
-//}
diff --git a/protocol/dubbo/client_test.go b/protocol/dubbo/client_test.go
deleted file mode 100644
index 4f5913c56f4c2d509b86de7b6fdf26ebee9e2727..0000000000000000000000000000000000000000
--- a/protocol/dubbo/client_test.go
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"bytes"
-//	"context"
-//	"sync"
-//	"testing"
-//	"time"
-//)
-//
-//import (
-//	hessian "github.com/apache/dubbo-go-hessian2"
-//	perrors "github.com/pkg/errors"
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/proxy/proxy_factory"
-//	"github.com/apache/dubbo-go/protocol"
-//)
-//
-//func TestClient_CallOneway(t *testing.T) {
-//	proto, url := InitTest(t)
-//
-//	c := &Client{
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//		opts: Options{
-//			ConnectTimeout: 3e9,
-//			RequestTimeout: 6e9,
-//		},
-//	}
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	//user := &User{}
-//	err := c.CallOneway(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil))
-//	assert.NoError(t, err)
-//
-//	// destroy
-//	proto.Destroy()
-//}
-//
-//func TestClient_Call(t *testing.T) {
-//	proto, url := InitTest(t)
-//
-//	c := &Client{
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//		opts: Options{
-//			ConnectTimeout: 3e9,
-//			RequestTimeout: 10e9,
-//		},
-//	}
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	var (
-//		user *User
-//		err  error
-//	)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetBigPkg", []interface{}{nil}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.NotEqual(t, "", user.Id)
-//	assert.NotEqual(t, "", user.Name)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "1", Name: "username"}, *user)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser0", []interface{}{"1", nil, "username"}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "1", Name: "username"}, *user)
-//
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser1", []interface{}{}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser2", []interface{}{}, nil), NewResponse(user, nil))
-//	assert.EqualError(t, err, "error")
-//
-//	user2 := []interface{}{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser3", []interface{}{}, nil), NewResponse(&user2, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
-//
-//	user2 = []interface{}{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser4", []interface{}{[]interface{}{"1", "username"}}, nil), NewResponse(&user2, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
-//
-//	user3 := map[interface{}]interface{}{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser5", []interface{}{map[interface{}]interface{}{"id": "1", "name": "username"}}, nil), NewResponse(&user3, nil))
-//	assert.NoError(t, err)
-//	assert.NotNil(t, user3)
-//	assert.Equal(t, &User{Id: "1", Name: "username"}, user3["key"])
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser6", []interface{}{0}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "", Name: ""}, *user)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser6", []interface{}{1}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "1", Name: ""}, *user)
-//
-//	// destroy
-//	proto.Destroy()
-//}
-//
-//func TestClient_AsyncCall(t *testing.T) {
-//	proto, url := InitTest(t)
-//
-//	c := &Client{
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//		opts: Options{
-//			ConnectTimeout: 3e9,
-//			RequestTimeout: 6e9,
-//		},
-//	}
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	user := &User{}
-//	lock := sync.Mutex{}
-//	lock.Lock()
-//	err := c.AsyncCall(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil), func(response common.CallbackResponse) {
-//		r := response.(AsyncCallbackResponse)
-//		assert.Equal(t, User{Id: "1", Name: "username"}, *r.Reply.(*Response).reply.(*User))
-//		lock.Unlock()
-//	}, NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{}, *user)
-//
-//	// destroy
-//	lock.Lock()
-//	proto.Destroy()
-//	lock.Unlock()
-//}
-//
-//func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
-//
-//	hessian.RegisterPOJO(&User{})
-//
-//	methods, err := common.ServiceMap.Register("dubbo", &UserProvider{})
-//	assert.NoError(t, err)
-//	assert.Equal(t, "GetBigPkg,GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4,GetUser5,GetUser6", methods)
-//
-//	// config
-//	SetClientConf(ClientConfig{
-//		ConnectionNum:   2,
-//		HeartbeatPeriod: "5s",
-//		SessionTimeout:  "20s",
-//		PoolTTL:         600,
-//		PoolSize:        64,
-//		GettySessionParam: GettySessionParam{
-//			CompressEncoding: false,
-//			TcpNoDelay:       true,
-//			TcpKeepAlive:     true,
-//			KeepAlivePeriod:  "120s",
-//			TcpRBufSize:      262144,
-//			TcpWBufSize:      65536,
-//			PkgWQSize:        512,
-//			TcpReadTimeout:   "4s",
-//			TcpWriteTimeout:  "5s",
-//			WaitTimeout:      "1s",
-//			MaxMsgLen:        10240000000,
-//			SessionName:      "client",
-//		},
-//	})
-//	assert.NoError(t, clientConf.CheckValidity())
-//	SetServerConfig(ServerConfig{
-//		SessionNumber:  700,
-//		SessionTimeout: "20s",
-//		GettySessionParam: GettySessionParam{
-//			CompressEncoding: false,
-//			TcpNoDelay:       true,
-//			TcpKeepAlive:     true,
-//			KeepAlivePeriod:  "120s",
-//			TcpRBufSize:      262144,
-//			TcpWBufSize:      65536,
-//			PkgWQSize:        512,
-//			TcpReadTimeout:   "1s",
-//			TcpWriteTimeout:  "5s",
-//			WaitTimeout:      "1s",
-//			MaxMsgLen:        10240000000,
-//			SessionName:      "server",
-//		}})
-//	assert.NoError(t, srvConf.CheckValidity())
-//
-//	// Export
-//	proto := GetProtocol()
-//	url, err := common.NewURL("dubbo://127.0.0.1:20000/UserProvider?anyhost=true&" +
-//		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
-//		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
-//		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
-//		"side=provider&timeout=3000&timestamp=1556509797245&bean.name=UserProvider")
-//	assert.NoError(t, err)
-//	proto.Export(&proxy_factory.ProxyInvoker{
-//		BaseInvoker: *protocol.NewBaseInvoker(url),
-//	})
-//
-//	time.Sleep(time.Second * 2)
-//
-//	return proto, url
-//}
-//
-////////////////////////////////////
-//// provider
-////////////////////////////////////
-//
-//type (
-//	User struct {
-//		Id   string `json:"id"`
-//		Name string `json:"name"`
-//	}
-//
-//	UserProvider struct {
-//		user map[string]User
-//	}
-//)
-//
-//// size:4801228
-//func (u *UserProvider) GetBigPkg(ctx context.Context, req []interface{}, rsp *User) error {
-//	argBuf := new(bytes.Buffer)
-//	for i := 0; i < 4000; i++ {
-//		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
-//		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
-//	}
-//	rsp.Id = argBuf.String()
-//	rsp.Name = argBuf.String()
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
-//	rsp.Id = req[0].(string)
-//	rsp.Name = req[1].(string)
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser0(id string, k *User, name string) (User, error) {
-//	return User{Id: id, Name: name}, nil
-//}
-//
-//func (u *UserProvider) GetUser1() error {
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser2() error {
-//	return perrors.New("error")
-//}
-//
-//func (u *UserProvider) GetUser3(rsp *[]interface{}) error {
-//	*rsp = append(*rsp, User{Id: "1", Name: "username"})
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser4(ctx context.Context, req []interface{}) ([]interface{}, error) {
-//
-//	return []interface{}{User{Id: req[0].([]interface{})[0].(string), Name: req[0].([]interface{})[1].(string)}}, nil
-//}
-//
-//func (u *UserProvider) GetUser5(ctx context.Context, req []interface{}) (map[interface{}]interface{}, error) {
-//	return map[interface{}]interface{}{"key": User{Id: req[0].(map[interface{}]interface{})["id"].(string), Name: req[0].(map[interface{}]interface{})["name"].(string)}}, nil
-//}
-//
-//func (u *UserProvider) GetUser6(id int64) (*User, error) {
-//	if id == 0 {
-//		return nil, nil
-//	}
-//	return &User{Id: "1"}, nil
-//}
-//
-//func (u *UserProvider) Reference() string {
-//	return "UserProvider"
-//}
-//
-//func (u User) JavaClassName() string {
-//	return "com.ikurento.user.User"
-//}
diff --git a/protocol/dubbo/codec.go b/protocol/dubbo/codec.go
deleted file mode 100644
index 8dd91c2d31e898def02d94ec0539e7a8acd2b818..0000000000000000000000000000000000000000
--- a/protocol/dubbo/codec.go
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"bufio"
-//	"bytes"
-//	"fmt"
-//	"time"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go-hessian2"
-//	"github.com/apache/dubbo-go/common"
-//	perrors "github.com/pkg/errors"
-//)
-//
-////SerialID serial ID
-//type SerialID byte
-//
-//const (
-//	// S_Dubbo dubbo serial id
-//	S_Dubbo SerialID = 2
-//)
-//
-////CallType call type
-//type CallType int32
-//
-//const (
-//	// CT_UNKNOWN unknown call type
-//	CT_UNKNOWN CallType = 0
-//	// CT_OneWay call one way
-//	CT_OneWay CallType = 1
-//	// CT_TwoWay call in request/response
-//	CT_TwoWay CallType = 2
-//)
-//
-//////////////////////////////////////////////
-//// dubbo package
-//////////////////////////////////////////////
-//
-//// SequenceType ...
-//type SequenceType int64
-//
-//// DubboPackage ...
-//type DubboPackage struct {
-//	Header  hessian.DubboHeader
-//	Service hessian.Service
-//	Body    interface{}
-//	Err     error
-//}
-//
-//func (p DubboPackage) String() string {
-//	return fmt.Sprintf("DubboPackage: Header-%v, Path-%v, Body-%v", p.Header, p.Service, p.Body)
-//}
-//
-//// Marshal ...
-//func (p *DubboPackage) Marshal() (*bytes.Buffer, error) {
-//	codec := hessian.NewHessianCodec(nil)
-//
-//	pkg, err := codec.Write(p.Service, p.Header, p.Body)
-//	if err != nil {
-//		return nil, perrors.WithStack(err)
-//	}
-//
-//	return bytes.NewBuffer(pkg), nil
-//}
-//
-//// Unmarshal ...
-//func (p *DubboPackage) Unmarshal(buf *bytes.Buffer, opts ...interface{}) error {
-//	// fix issue https://github.com/apache/dubbo-go/issues/380
-//	bufLen := buf.Len()
-//	if bufLen < hessian.HEADER_LENGTH {
-//		return perrors.WithStack(hessian.ErrHeaderNotEnough)
-//	}
-//
-//	codec := hessian.NewHessianCodec(bufio.NewReaderSize(buf, bufLen))
-//
-//	// read header
-//	err := codec.ReadHeader(&p.Header)
-//	if err != nil {
-//		return perrors.WithStack(err)
-//	}
-//
-//	if len(opts) != 0 { // for client
-//		client, ok := opts[0].(*Client)
-//		if !ok {
-//			return perrors.Errorf("opts[0] is not of type *Client")
-//		}
-//
-//		if p.Header.Type&hessian.PackageRequest != 0x00 {
-//			// size of this array must be '7'
-//			// https://github.com/apache/dubbo-go-hessian2/blob/master/request.go#L272
-//			p.Body = make([]interface{}, 7)
-//		} else {
-//			pendingRsp, ok := client.pendingResponses.Load(SequenceType(p.Header.ID))
-//			if !ok {
-//				return perrors.Errorf("client.GetPendingResponse(%v) = nil", p.Header.ID)
-//			}
-//			p.Body = &hessian.Response{RspObj: pendingRsp.(*PendingResponse).response.reply}
-//		}
-//	}
-//
-//	// read body
-//	err = codec.ReadBody(p.Body)
-//	return perrors.WithStack(err)
-//}
-//
-//////////////////////////////////////////////
-//// PendingResponse
-//////////////////////////////////////////////
-//
-//// PendingResponse ...
-//type PendingResponse struct {
-//	seq       uint64
-//	err       error
-//	start     time.Time
-//	readStart time.Time
-//	callback  common.AsyncCallback
-//	response  *Response
-//	done      chan struct{}
-//}
-//
-//// NewPendingResponse ...
-//func NewPendingResponse() *PendingResponse {
-//	return &PendingResponse{
-//		start:    time.Now(),
-//		response: &Response{},
-//		done:     make(chan struct{}),
-//	}
-//}
-//
-//// GetCallResponse ...
-//func (r PendingResponse) GetCallResponse() common.CallbackResponse {
-//	return AsyncCallbackResponse{
-//		Cause:     r.err,
-//		Start:     r.start,
-//		ReadStart: r.readStart,
-//		Reply:     r.response,
-//	}
-//}
diff --git a/protocol/dubbo/codec_test.go b/protocol/dubbo/codec_test.go
deleted file mode 100644
index c9599da6c76799e05dc4b96a00b958409bcc846b..0000000000000000000000000000000000000000
--- a/protocol/dubbo/codec_test.go
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"bytes"
-//	"testing"
-//	"time"
-//)
-//
-//import (
-//	hessian "github.com/apache/dubbo-go-hessian2"
-//	perrors "github.com/pkg/errors"
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//func TestDubboPackage_MarshalAndUnmarshal(t *testing.T) {
-//	pkg := &DubboPackage{}
-//	pkg.Body = []interface{}{"a"}
-//	pkg.Header.Type = hessian.PackageHeartbeat
-//	pkg.Header.SerialID = byte(S_Dubbo)
-//	pkg.Header.ID = 10086
-//
-//	// heartbeat
-//	data, err := pkg.Marshal()
-//	assert.NoError(t, err)
-//
-//	pkgres := &DubboPackage{}
-//	pkgres.Body = []interface{}{}
-//	err = pkgres.Unmarshal(data)
-//	assert.NoError(t, err)
-//	assert.Equal(t, hessian.PackageHeartbeat|hessian.PackageRequest|hessian.PackageRequest_TwoWay, pkgres.Header.Type)
-//	assert.Equal(t, byte(S_Dubbo), pkgres.Header.SerialID)
-//	assert.Equal(t, int64(10086), pkgres.Header.ID)
-//	assert.Equal(t, 0, len(pkgres.Body.([]interface{})))
-//
-//	// request
-//	pkg.Header.Type = hessian.PackageRequest
-//	pkg.Service.Interface = "Service"
-//	pkg.Service.Path = "path"
-//	pkg.Service.Version = "2.6"
-//	pkg.Service.Method = "Method"
-//	pkg.Service.Timeout = time.Second
-//	data, err = pkg.Marshal()
-//	assert.NoError(t, err)
-//
-//	pkgres = &DubboPackage{}
-//	pkgres.Body = make([]interface{}, 7)
-//	err = pkgres.Unmarshal(data)
-//	assert.NoError(t, err)
-//	assert.Equal(t, hessian.PackageRequest, pkgres.Header.Type)
-//	assert.Equal(t, byte(S_Dubbo), pkgres.Header.SerialID)
-//	assert.Equal(t, int64(10086), pkgres.Header.ID)
-//	assert.Equal(t, "2.0.2", pkgres.Body.([]interface{})[0])
-//	assert.Equal(t, "path", pkgres.Body.([]interface{})[1])
-//	assert.Equal(t, "2.6", pkgres.Body.([]interface{})[2])
-//	assert.Equal(t, "Method", pkgres.Body.([]interface{})[3])
-//	assert.Equal(t, "Ljava/lang/String;", pkgres.Body.([]interface{})[4])
-//	assert.Equal(t, []interface{}{"a"}, pkgres.Body.([]interface{})[5])
-//	assert.Equal(t, map[string]string{"dubbo": "2.0.2", "interface": "Service", "path": "path", "timeout": "1000", "version": "2.6"}, pkgres.Body.([]interface{})[6])
-//}
-//
-//func TestIssue380(t *testing.T) {
-//	pkg := &DubboPackage{}
-//	buf := bytes.NewBuffer([]byte("hello"))
-//	err := pkg.Unmarshal(buf)
-//	assert.True(t, perrors.Cause(err) == hessian.ErrHeaderNotEnough)
-//}
diff --git a/protocol/dubbo/config.go b/protocol/dubbo/config.go
deleted file mode 100644
index f00931e00fb011e30a60f47d0cdd234446180534..0000000000000000000000000000000000000000
--- a/protocol/dubbo/config.go
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"time"
-//)
-//
-//import (
-//	"github.com/dubbogo/getty"
-//	perrors "github.com/pkg/errors"
-//)
-//
-//type (
-//	// GettySessionParam ...
-//	GettySessionParam struct {
-//		CompressEncoding bool   `default:"false" yaml:"compress_encoding" json:"compress_encoding,omitempty"`
-//		TcpNoDelay       bool   `default:"true" yaml:"tcp_no_delay" json:"tcp_no_delay,omitempty"`
-//		TcpKeepAlive     bool   `default:"true" yaml:"tcp_keep_alive" json:"tcp_keep_alive,omitempty"`
-//		KeepAlivePeriod  string `default:"180s" yaml:"keep_alive_period" json:"keep_alive_period,omitempty"`
-//		keepAlivePeriod  time.Duration
-//		TcpRBufSize      int    `default:"262144" yaml:"tcp_r_buf_size" json:"tcp_r_buf_size,omitempty"`
-//		TcpWBufSize      int    `default:"65536" yaml:"tcp_w_buf_size" json:"tcp_w_buf_size,omitempty"`
-//		PkgWQSize        int    `default:"1024" yaml:"pkg_wq_size" json:"pkg_wq_size,omitempty"`
-//		TcpReadTimeout   string `default:"1s" yaml:"tcp_read_timeout" json:"tcp_read_timeout,omitempty"`
-//		tcpReadTimeout   time.Duration
-//		TcpWriteTimeout  string `default:"5s" yaml:"tcp_write_timeout" json:"tcp_write_timeout,omitempty"`
-//		tcpWriteTimeout  time.Duration
-//		WaitTimeout      string `default:"7s" yaml:"wait_timeout" json:"wait_timeout,omitempty"`
-//		waitTimeout      time.Duration
-//		MaxMsgLen        int    `default:"1024" yaml:"max_msg_len" json:"max_msg_len,omitempty"`
-//		SessionName      string `default:"rpc" yaml:"session_name" json:"session_name,omitempty"`
-//	}
-//
-//	// ServerConfig
-//	//Config holds supported types by the multiconfig package
-//	ServerConfig struct {
-//		// session
-//		SessionTimeout string `default:"60s" yaml:"session_timeout" json:"session_timeout,omitempty"`
-//		sessionTimeout time.Duration
-//		SessionNumber  int `default:"1000" yaml:"session_number" json:"session_number,omitempty"`
-//
-//		// grpool
-//		GrPoolSize  int `default:"0" yaml:"gr_pool_size" json:"gr_pool_size,omitempty"`
-//		QueueLen    int `default:"0" yaml:"queue_len" json:"queue_len,omitempty"`
-//		QueueNumber int `default:"0" yaml:"queue_number" json:"queue_number,omitempty"`
-//
-//		// session tcp parameters
-//		GettySessionParam GettySessionParam `required:"true" yaml:"getty_session_param" json:"getty_session_param,omitempty"`
-//	}
-//
-//	// ClientConfig
-//	//Config holds supported types by the multiconfig package
-//	ClientConfig struct {
-//		ReconnectInterval int `default:"0" yaml:"reconnect_interval" json:"reconnect_interval,omitempty"`
-//
-//		// session pool
-//		ConnectionNum int `default:"16" yaml:"connection_number" json:"connection_number,omitempty"`
-//
-//		// heartbeat
-//		HeartbeatPeriod string `default:"15s" yaml:"heartbeat_period" json:"heartbeat_period,omitempty"`
-//		heartbeatPeriod time.Duration
-//
-//		// session
-//		SessionTimeout string `default:"60s" yaml:"session_timeout" json:"session_timeout,omitempty"`
-//		sessionTimeout time.Duration
-//
-//		// Connection Pool
-//		PoolSize int `default:"2" yaml:"pool_size" json:"pool_size,omitempty"`
-//		PoolTTL  int `default:"180" yaml:"pool_ttl" json:"pool_ttl,omitempty"`
-//
-//		// grpool
-//		GrPoolSize  int `default:"0" yaml:"gr_pool_size" json:"gr_pool_size,omitempty"`
-//		QueueLen    int `default:"0" yaml:"queue_len" json:"queue_len,omitempty"`
-//		QueueNumber int `default:"0" yaml:"queue_number" json:"queue_number,omitempty"`
-//
-//		// session tcp parameters
-//		GettySessionParam GettySessionParam `required:"true" yaml:"getty_session_param" json:"getty_session_param,omitempty"`
-//	}
-//)
-//
-//// GetDefaultClientConfig ...
-//func GetDefaultClientConfig() ClientConfig {
-//	return ClientConfig{
-//		ReconnectInterval: 0,
-//		ConnectionNum:     16,
-//		HeartbeatPeriod:   "30s",
-//		SessionTimeout:    "180s",
-//		PoolSize:          4,
-//		PoolTTL:           600,
-//		GrPoolSize:        200,
-//		QueueLen:          64,
-//		QueueNumber:       10,
-//		GettySessionParam: GettySessionParam{
-//			CompressEncoding: false,
-//			TcpNoDelay:       true,
-//			TcpKeepAlive:     true,
-//			KeepAlivePeriod:  "180s",
-//			TcpRBufSize:      262144,
-//			TcpWBufSize:      65536,
-//			PkgWQSize:        512,
-//			TcpReadTimeout:   "1s",
-//			TcpWriteTimeout:  "5s",
-//			WaitTimeout:      "1s",
-//			MaxMsgLen:        102400,
-//			SessionName:      "client",
-//		}}
-//}
-//
-//// GetDefaultServerConfig ...
-//func GetDefaultServerConfig() ServerConfig {
-//	return ServerConfig{
-//		SessionTimeout: "180s",
-//		SessionNumber:  700,
-//		GrPoolSize:     120,
-//		QueueNumber:    6,
-//		QueueLen:       64,
-//		GettySessionParam: GettySessionParam{
-//			CompressEncoding: false,
-//			TcpNoDelay:       true,
-//			TcpKeepAlive:     true,
-//			KeepAlivePeriod:  "180s",
-//			TcpRBufSize:      262144,
-//			TcpWBufSize:      65536,
-//			PkgWQSize:        512,
-//			TcpReadTimeout:   "1s",
-//			TcpWriteTimeout:  "5s",
-//			WaitTimeout:      "1s",
-//			MaxMsgLen:        102400,
-//			SessionName:      "server",
-//		},
-//	}
-//}
-//
-//// CheckValidity ...
-//func (c *GettySessionParam) CheckValidity() error {
-//	var err error
-//
-//	if c.keepAlivePeriod, err = time.ParseDuration(c.KeepAlivePeriod); err != nil {
-//		return perrors.WithMessagef(err, "time.ParseDuration(KeepAlivePeriod{%#v})", c.KeepAlivePeriod)
-//	}
-//
-//	if c.tcpReadTimeout, err = time.ParseDuration(c.TcpReadTimeout); err != nil {
-//		return perrors.WithMessagef(err, "time.ParseDuration(TcpReadTimeout{%#v})", c.TcpReadTimeout)
-//	}
-//
-//	if c.tcpWriteTimeout, err = time.ParseDuration(c.TcpWriteTimeout); err != nil {
-//		return perrors.WithMessagef(err, "time.ParseDuration(TcpWriteTimeout{%#v})", c.TcpWriteTimeout)
-//	}
-//
-//	if c.waitTimeout, err = time.ParseDuration(c.WaitTimeout); err != nil {
-//		return perrors.WithMessagef(err, "time.ParseDuration(WaitTimeout{%#v})", c.WaitTimeout)
-//	}
-//
-//	return nil
-//}
-//
-//// CheckValidity ...
-//func (c *ClientConfig) CheckValidity() error {
-//	var err error
-//
-//	c.ReconnectInterval = c.ReconnectInterval * 1e6
-//
-//	if c.heartbeatPeriod, err = time.ParseDuration(c.HeartbeatPeriod); err != nil {
-//		return perrors.WithMessagef(err, "time.ParseDuration(HeartbeatPeroid{%#v})", c.HeartbeatPeriod)
-//	}
-//
-//	if c.heartbeatPeriod >= time.Duration(getty.MaxWheelTimeSpan) {
-//		return perrors.WithMessagef(err, "heartbeat_period %s should be less than %s",
-//			c.HeartbeatPeriod, time.Duration(getty.MaxWheelTimeSpan))
-//	}
-//
-//	if c.sessionTimeout, err = time.ParseDuration(c.SessionTimeout); err != nil {
-//		return perrors.WithMessagef(err, "time.ParseDuration(SessionTimeout{%#v})", c.SessionTimeout)
-//	}
-//
-//	return perrors.WithStack(c.GettySessionParam.CheckValidity())
-//}
-//
-//// CheckValidity ...
-//func (c *ServerConfig) CheckValidity() error {
-//	var err error
-//
-//	if c.sessionTimeout, err = time.ParseDuration(c.SessionTimeout); err != nil {
-//		return perrors.WithMessagef(err, "time.ParseDuration(SessionTimeout{%#v})", c.SessionTimeout)
-//	}
-//
-//	if c.sessionTimeout >= time.Duration(getty.MaxWheelTimeSpan) {
-//		return perrors.WithMessagef(err, "session_timeout %s should be less than %s",
-//			c.SessionTimeout, time.Duration(getty.MaxWheelTimeSpan))
-//	}
-//
-//	return perrors.WithStack(c.GettySessionParam.CheckValidity())
-//}
diff --git a/protocol/dubbo/dubbo_codec.go b/protocol/dubbo/dubbo_codec.go
index 899148a8e06226a6318564c42367b4fee025eff5..c1f8231385dd788e3900eeb8db7f7b62d08bc498 100644
--- a/protocol/dubbo/dubbo_codec.go
+++ b/protocol/dubbo/dubbo_codec.go
@@ -4,6 +4,9 @@ import (
 	"bufio"
 	"bytes"
 	"fmt"
+	"strconv"
+	"time"
+
 	hessian "github.com/apache/dubbo-go-hessian2"
 	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/common/logger"
@@ -11,8 +14,6 @@ import (
 	"github.com/apache/dubbo-go/protocol/invocation"
 	"github.com/apache/dubbo-go/remoting"
 	perrors "github.com/pkg/errors"
-	"strconv"
-	"time"
 )
 
 //SerialID serial ID
@@ -171,8 +172,9 @@ func (c *DubboCodec) EncodeResponse(response *remoting.Response) (*bytes.Buffer,
 	}
 	if !response.IsHeartbeat() {
 		resp.Body = &hessian.Response{
-			RspObj:    response.Result.(protocol.RPCResult).Rest,
-			Exception: response.Result.(protocol.RPCResult).Err,
+			RspObj:      response.Result.(protocol.RPCResult).Rest,
+			Exception:   response.Result.(protocol.RPCResult).Err,
+			Attachments: response.Result.(protocol.RPCResult).Attrs,
 		}
 	}
 
@@ -190,7 +192,29 @@ func (c *DubboCodec) EncodeResponse(response *remoting.Response) (*bytes.Buffer,
 
 	return bytes.NewBuffer(pkg), nil
 }
-func (c *DubboCodec) DecodeRequest(data []byte) (*remoting.Request, int, error) {
+func (c *DubboCodec) Decode(data []byte) (remoting.DecodeResult, int, error) {
+	if c.isRequest(data) {
+		req, len, err := c.decodeRequest(data)
+		if err != nil {
+			return remoting.DecodeResult{}, len, err
+		}
+		return remoting.DecodeResult{IsRequest: true, Result: req}, len, err
+	} else {
+		resp, len, err := c.decodeResponse(data)
+		if err != nil {
+			return remoting.DecodeResult{}, len, err
+		}
+		return remoting.DecodeResult{IsRequest: false, Result: resp}, len, err
+	}
+}
+func (c *DubboCodec) isRequest(data []byte) bool {
+	if data[2]&byte(0x80) == 0x00 {
+		return false
+	}
+	return true
+}
+
+func (c *DubboCodec) decodeRequest(data []byte) (*remoting.Request, int, error) {
 	pkg := &DubboPackage{
 		Body: make([]interface{}, 7),
 	}
@@ -201,7 +225,7 @@ func (c *DubboCodec) DecodeRequest(data []byte) (*remoting.Request, int, error)
 		originErr := perrors.Cause(err)
 		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
 			//FIXME
-			return request, 0, originErr
+			return nil, 0, originErr
 		}
 		logger.Errorf("pkg.Unmarshal(len(@data):%d) = error:%+v", buf.Len(), err)
 
@@ -274,7 +298,7 @@ func (c *DubboCodec) DecodeRequest(data []byte) (*remoting.Request, int, error)
 	return request, hessian.HEADER_LENGTH + pkg.Header.BodyLen, nil
 }
 
-func (c *DubboCodec) DecodeResponse(data []byte) (*remoting.Response, int, error) {
+func (c *DubboCodec) decodeResponse(data []byte) (*remoting.Response, int, error) {
 	pkg := &DubboPackage{}
 	buf := bytes.NewBuffer(data)
 	response := &remoting.Response{}
@@ -282,11 +306,11 @@ func (c *DubboCodec) DecodeResponse(data []byte) (*remoting.Response, int, error
 	if err != nil {
 		originErr := perrors.Cause(err)
 		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
-			return response, 0, nil
+			return nil, 0, originErr
 		}
 		logger.Errorf("pkg.Unmarshal(len(@data):%d) = error:%+v", buf.Len(), err)
 
-		return response, 0, perrors.WithStack(err)
+		return nil, 0, perrors.WithStack(err)
 	}
 	response = &remoting.Response{
 		Id: pkg.Header.ID,
@@ -316,6 +340,9 @@ func (c *DubboCodec) DecodeResponse(data []byte) (*remoting.Response, int, error
 	if pkg.Header.Type&hessian.PackageRequest == 0x00 {
 		if pkg.Err != nil {
 			rpcResult.Err = pkg.Err
+		} else if pkg.Body.(*hessian.Response).Exception != nil {
+			rpcResult.Err = pkg.Body.(*hessian.Response).Exception
+			response.Error = rpcResult.Err
 		}
 		rpcResult.Attrs = pkg.Body.(*hessian.Response).Attachments
 		rpcResult.Rest = pkg.Body.(*hessian.Response).RspObj
diff --git a/protocol/dubbo/dubbo_codec_test.go b/protocol/dubbo/dubbo_codec_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f401318d86115f58578a6470227ea6e6afe811a7
--- /dev/null
+++ b/protocol/dubbo/dubbo_codec_test.go
@@ -0,0 +1 @@
+package dubbo
diff --git a/protocol/dubbo/dubbo_invoker_test.go b/protocol/dubbo/dubbo_invoker_test.go
index 1a64301f8200a4264001284cca1af3f0f1e07814..ddb7b783d121c068d99ba20b92cb163549a73756 100644
--- a/protocol/dubbo/dubbo_invoker_test.go
+++ b/protocol/dubbo/dubbo_invoker_test.go
@@ -18,35 +18,31 @@
 package dubbo
 
 import (
+	"bytes"
 	"context"
 	"sync"
 	"testing"
 	"time"
-)
 
-import (
-	"github.com/opentracing/opentracing-go"
-	"github.com/stretchr/testify/assert"
-)
+	"github.com/apache/dubbo-go/remoting"
 
-import (
+	"github.com/apache/dubbo-go/remoting/getty"
+
+	hessian "github.com/apache/dubbo-go-hessian2"
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/proxy/proxy_factory"
+	"github.com/apache/dubbo-go/protocol"
 	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/opentracing/opentracing-go"
+	perrors "github.com/pkg/errors"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestDubboInvoker_Invoke(t *testing.T) {
 	proto, url := InitTest(t)
 
-	c := &Client{
-		pendingResponses: new(sync.Map),
-		conf:             *clientConf,
-		opts: Options{
-			ConnectTimeout: 3 * time.Second,
-			RequestTimeout: 6 * time.Second,
-		},
-	}
-	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
+	c := getExchangeClient(url)
 
 	invoker := NewDubboInvoker(url, c)
 	user := &User{}
@@ -58,7 +54,9 @@ func TestDubboInvoker_Invoke(t *testing.T) {
 	res := invoker.Invoke(context.Background(), inv)
 	assert.NoError(t, res.Error())
 	assert.Equal(t, User{Id: "1", Name: "username"}, *res.Result().(*User))
-	assert.Equal(t, "test_value", res.Attachments()["test_key"]) // test attachments for request/response
+	//result will not contain attachment
+	// attachment in result it is useless.
+	//assert.Equal(t, "test_value", res.Attachments()["test_key"]) // test attachments for request/response
 
 	// CallOneway
 	inv.SetAttachments(constant.ASYNC_KEY, "true")
@@ -69,8 +67,10 @@ func TestDubboInvoker_Invoke(t *testing.T) {
 	lock := sync.Mutex{}
 	lock.Lock()
 	inv.SetCallBack(func(response common.CallbackResponse) {
-		r := response.(AsyncCallbackResponse)
-		assert.Equal(t, User{Id: "1", Name: "username"}, *r.Reply.(*Response).reply.(*User))
+		r := response.(remoting.AsyncCallbackResponse)
+		rst := *r.Reply.(*remoting.Response).Result.(*protocol.RPCResult)
+		assert.Equal(t, User{Id: "1", Name: "username"}, *(rst.Rest.(*User)))
+		//assert.Equal(t, User{Id: "1", Name: "username"}, *r.Reply.(*Response).reply.(*User))
 		lock.Unlock()
 	})
 	res = invoker.Invoke(context.Background(), inv)
@@ -92,3 +92,142 @@ func TestDubboInvoker_Invoke(t *testing.T) {
 	proto.Destroy()
 	lock.Unlock()
 }
+
+func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
+
+	hessian.RegisterPOJO(&User{})
+
+	methods, err := common.ServiceMap.Register("dubbo", &UserProvider{})
+	assert.NoError(t, err)
+	assert.Equal(t, "GetBigPkg,GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4,GetUser5,GetUser6", methods)
+
+	// config
+	getty.SetClientConf(getty.ClientConfig{
+		ConnectionNum:   2,
+		HeartbeatPeriod: "5s",
+		SessionTimeout:  "20s",
+		PoolTTL:         600,
+		PoolSize:        64,
+		GettySessionParam: getty.GettySessionParam{
+			CompressEncoding: false,
+			TcpNoDelay:       true,
+			TcpKeepAlive:     true,
+			KeepAlivePeriod:  "120s",
+			TcpRBufSize:      262144,
+			TcpWBufSize:      65536,
+			PkgWQSize:        512,
+			TcpReadTimeout:   "4s",
+			TcpWriteTimeout:  "5s",
+			WaitTimeout:      "1s",
+			MaxMsgLen:        10240000000,
+			SessionName:      "client",
+		},
+	})
+	getty.SetServerConfig(getty.ServerConfig{
+		SessionNumber:  700,
+		SessionTimeout: "20s",
+		GettySessionParam: getty.GettySessionParam{
+			CompressEncoding: false,
+			TcpNoDelay:       true,
+			TcpKeepAlive:     true,
+			KeepAlivePeriod:  "120s",
+			TcpRBufSize:      262144,
+			TcpWBufSize:      65536,
+			PkgWQSize:        512,
+			TcpReadTimeout:   "1s",
+			TcpWriteTimeout:  "5s",
+			WaitTimeout:      "1s",
+			MaxMsgLen:        10240000000,
+			SessionName:      "server",
+		}})
+
+	// Export
+	proto := GetProtocol()
+	url, err := common.NewURL("dubbo://127.0.0.1:20702/UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=1556509797245&bean.name=UserProvider")
+	assert.NoError(t, err)
+	proto.Export(&proxy_factory.ProxyInvoker{
+		BaseInvoker: *protocol.NewBaseInvoker(url),
+	})
+
+	time.Sleep(time.Second * 2)
+
+	return proto, url
+}
+
+//////////////////////////////////
+// provider
+//////////////////////////////////
+
+type (
+	User struct {
+		Id   string `json:"id"`
+		Name string `json:"name"`
+	}
+
+	UserProvider struct {
+		user map[string]User
+	}
+)
+
+// size:4801228
+func (u *UserProvider) GetBigPkg(ctx context.Context, req []interface{}, rsp *User) error {
+	argBuf := new(bytes.Buffer)
+	for i := 0; i < 400; i++ {
+		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
+		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
+	}
+	rsp.Id = argBuf.String()
+	rsp.Name = argBuf.String()
+	return nil
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	rsp.Id = req[0].(string)
+	rsp.Name = req[1].(string)
+	return nil
+}
+
+func (u *UserProvider) GetUser0(id string, k *User, name string) (User, error) {
+	return User{Id: id, Name: name}, nil
+}
+
+func (u *UserProvider) GetUser1() error {
+	return nil
+}
+
+func (u *UserProvider) GetUser2() error {
+	return perrors.New("error")
+}
+
+func (u *UserProvider) GetUser3(rsp *[]interface{}) error {
+	*rsp = append(*rsp, User{Id: "1", Name: "username"})
+	return nil
+}
+
+func (u *UserProvider) GetUser4(ctx context.Context, req []interface{}) ([]interface{}, error) {
+
+	return []interface{}{User{Id: req[0].([]interface{})[0].(string), Name: req[0].([]interface{})[1].(string)}}, nil
+}
+
+func (u *UserProvider) GetUser5(ctx context.Context, req []interface{}) (map[interface{}]interface{}, error) {
+	return map[interface{}]interface{}{"key": User{Id: req[0].(map[interface{}]interface{})["id"].(string), Name: req[0].(map[interface{}]interface{})["name"].(string)}}, nil
+}
+
+func (u *UserProvider) GetUser6(id int64) (*User, error) {
+	if id == 0 {
+		return nil, nil
+	}
+	return &User{Id: "1"}, nil
+}
+
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
+
+func (u User) JavaClassName() string {
+	return "com.ikurento.user.User"
+}
diff --git a/protocol/dubbo/dubbo_protocol.go b/protocol/dubbo/dubbo_protocol.go
index 20e54fa2ee95170ed7ca94b2ccd4e0d5d9a29922..3bf03419239e85a5d71baded13965cb78f158231 100644
--- a/protocol/dubbo/dubbo_protocol.go
+++ b/protocol/dubbo/dubbo_protocol.go
@@ -18,19 +18,20 @@
 package dubbo
 
 import (
+	"context"
 	"fmt"
-	"github.com/apache/dubbo-go/protocol/invocation"
-	"github.com/apache/dubbo-go/remoting"
-	"github.com/apache/dubbo-go/remoting/getty"
 	"sync"
-)
 
-import (
 	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
 	"github.com/apache/dubbo-go/common/extension"
 	"github.com/apache/dubbo-go/common/logger"
 	"github.com/apache/dubbo-go/config"
 	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/remoting"
+	"github.com/apache/dubbo-go/remoting/getty"
+	"github.com/opentracing/opentracing-go"
 )
 
 // dubbo protocol constant
@@ -154,14 +155,8 @@ func doHandleRequest(rpcInvocation *invocation.RPCInvocation) protocol.RPCResult
 	}
 	invoker := exporter.(protocol.Exporter).GetInvoker()
 	if invoker != nil {
-		//attachments := rpcInvocation.Attachments()
-		//attachments[constant.LOCAL_ADDR] = session.LocalAddr()
-		//attachments[constant.REMOTE_ADDR] = session.RemoteAddr()
-		//
-		//args := p.Body.(map[string]interface{})["args"].([]interface{})
-		//inv := invocation.NewRPCInvocation(p.Service.Method, args, attachments)
 		// FIXME
-		ctx := getty.RebuildCtx(rpcInvocation)
+		ctx := rebuildCtx(rpcInvocation)
 
 		invokeResult := invoker.Invoke(ctx, rpcInvocation)
 		if err := invokeResult.Error(); err != nil {
@@ -200,3 +195,18 @@ func getExchangeClient(url common.URL) *remoting.ExchangeClient {
 	}
 	return exchangeClient
 }
+
+// rebuildCtx rebuild the context by attachment.
+// Once we decided to transfer more context's key-value, we should change this.
+// now we only support rebuild the tracing context
+func rebuildCtx(inv *invocation.RPCInvocation) context.Context {
+	ctx := context.WithValue(context.Background(), "attachment", inv.Attachments())
+
+	// actually, if user do not use any opentracing framework, the err will not be nil.
+	spanCtx, err := opentracing.GlobalTracer().Extract(opentracing.TextMap,
+		opentracing.TextMapCarrier(inv.Attachments()))
+	if err == nil {
+		ctx = context.WithValue(ctx, constant.TRACING_REMOTE_SPAN_CTX, spanCtx)
+	}
+	return ctx
+}
diff --git a/protocol/dubbo/dubbo_protocol_test.go b/protocol/dubbo/dubbo_protocol_test.go
index 5fdcc69b5c6ba409cf68954f95c2adf581297e4a..932e94862dd1a5c92a1f416482e8b61e574cc85c 100644
--- a/protocol/dubbo/dubbo_protocol_test.go
+++ b/protocol/dubbo/dubbo_protocol_test.go
@@ -16,84 +16,80 @@
  */
 
 package dubbo
-//
-//import (
-//	"testing"
-//)
-//
-//import (
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/constant"
-//	"github.com/apache/dubbo-go/protocol"
-//)
-//
-//func TestDubboProtocol_Export(t *testing.T) {
-//	// Export
-//	proto := GetProtocol()
-//	srvConf = &ServerConfig{}
-//	url, err := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
-//		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
-//		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
-//		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
-//		"side=provider&timeout=3000&timestamp=1556509797245")
-//	assert.NoError(t, err)
-//	exporter := proto.Export(protocol.NewBaseInvoker(url))
-//
-//	// make sure url
-//	eq := exporter.GetInvoker().GetUrl().URLEqual(url)
-//	assert.True(t, eq)
-//
-//	// second service: the same path and the different version
-//	url2, err := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&"+
-//		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+
-//		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+
-//		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
-//		"side=provider&timeout=3000&timestamp=1556509797245", common.WithParamsValue(constant.VERSION_KEY, "v1.1"))
-//	assert.NoError(t, err)
-//	exporter2 := proto.Export(protocol.NewBaseInvoker(url2))
-//	// make sure url
-//	eq2 := exporter2.GetInvoker().GetUrl().URLEqual(url2)
-//	assert.True(t, eq2)
-//
-//	// make sure exporterMap after 'Unexport'
-//	_, ok := proto.(*DubboProtocol).ExporterMap().Load(url.ServiceKey())
-//	assert.True(t, ok)
-//	exporter.Unexport()
-//	_, ok = proto.(*DubboProtocol).ExporterMap().Load(url.ServiceKey())
-//	assert.False(t, ok)
-//
-//	// make sure serverMap after 'Destroy'
-//	_, ok = proto.(*DubboProtocol).serverMap[url.Location]
-//	assert.True(t, ok)
-//	proto.Destroy()
-//	_, ok = proto.(*DubboProtocol).serverMap[url.Location]
-//	assert.False(t, ok)
-//}
-//
-//func TestDubboProtocol_Refer(t *testing.T) {
-//	// Refer
-//	proto := GetProtocol()
-//	url, err := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
-//		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
-//		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
-//		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
-//		"side=provider&timeout=3000&timestamp=1556509797245")
-//	assert.NoError(t, err)
-//	clientConf = &ClientConfig{}
-//	invoker := proto.Refer(url)
-//
-//	// make sure url
-//	eq := invoker.GetUrl().URLEqual(url)
-//	assert.True(t, eq)
-//
-//	// make sure invokers after 'Destroy'
-//	invokersLen := len(proto.(*DubboProtocol).Invokers())
-//	assert.Equal(t, 1, invokersLen)
-//	proto.Destroy()
-//	invokersLen = len(proto.(*DubboProtocol).Invokers())
-//	assert.Equal(t, 0, invokersLen)
-//}
+
+import (
+	"testing"
+
+	"github.com/apache/dubbo-go/common"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/remoting/getty"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDubboProtocol_Export(t *testing.T) {
+	// Export
+	proto := GetProtocol()
+	getty.SetServerConfig(getty.ServerConfig{})
+	url, err := common.NewURL("dubbo://127.0.0.1:20080/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=1556509797245")
+	assert.NoError(t, err)
+	exporter := proto.Export(protocol.NewBaseInvoker(url))
+
+	// make sure url
+	eq := exporter.GetInvoker().GetUrl().URLEqual(url)
+	assert.True(t, eq)
+
+	// second service: the same path and the different version
+	url2, err := common.NewURL("dubbo://127.0.0.1:20080/com.ikurento.user.UserProvider?anyhost=true&"+
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&"+
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&"+
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&"+
+		"side=provider&timeout=3000&timestamp=1556509797245", common.WithParamsValue(constant.VERSION_KEY, "v1.1"))
+	assert.NoError(t, err)
+	exporter2 := proto.Export(protocol.NewBaseInvoker(url2))
+	// make sure url
+	eq2 := exporter2.GetInvoker().GetUrl().URLEqual(url2)
+	assert.True(t, eq2)
+
+	// make sure exporterMap after 'Unexport'
+	_, ok := proto.(*DubboProtocol).ExporterMap().Load(url.ServiceKey())
+	assert.True(t, ok)
+	exporter.Unexport()
+	_, ok = proto.(*DubboProtocol).ExporterMap().Load(url.ServiceKey())
+	assert.False(t, ok)
+
+	// make sure serverMap after 'Destroy'
+	_, ok = proto.(*DubboProtocol).serverMap[url.Location]
+	assert.True(t, ok)
+	proto.Destroy()
+	_, ok = proto.(*DubboProtocol).serverMap[url.Location]
+	assert.False(t, ok)
+}
+
+func TestDubboProtocol_Refer(t *testing.T) {
+	// Refer
+	proto := GetProtocol()
+	url, err := common.NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=1556509797245")
+	assert.NoError(t, err)
+	getty.SetClientConf(getty.ClientConfig{})
+	invoker := proto.Refer(url)
+
+	// make sure url
+	eq := invoker.GetUrl().URLEqual(url)
+	assert.True(t, eq)
+
+	// make sure invokers after 'Destroy'
+	invokersLen := len(proto.(*DubboProtocol).Invokers())
+	assert.Equal(t, 1, invokersLen)
+	proto.Destroy()
+	invokersLen = len(proto.(*DubboProtocol).Invokers())
+	assert.Equal(t, 0, invokersLen)
+}
diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go
deleted file mode 100644
index 3d4db11f3dd80055cee259741f763c514c0a32c1..0000000000000000000000000000000000000000
--- a/protocol/dubbo/listener.go
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"context"
-//	"fmt"
-//	"net/url"
-//	"sync"
-//	"sync/atomic"
-//	"time"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go-hessian2"
-//	"github.com/dubbogo/getty"
-//	"github.com/opentracing/opentracing-go"
-//	perrors "github.com/pkg/errors"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/constant"
-//	"github.com/apache/dubbo-go/common/logger"
-//	"github.com/apache/dubbo-go/protocol"
-//	"github.com/apache/dubbo-go/protocol/invocation"
-//)
-//
-//// todo: WritePkg_Timeout will entry *.yml
-//const (
-//	// WritePkg_Timeout ...
-//	WritePkg_Timeout = 5 * time.Second
-//)
-//
-//var (
-//	errTooManySessions = perrors.New("too many sessions")
-//)
-//
-//type rpcSession struct {
-//	session getty.Session
-//	reqNum  int32
-//}
-//
-//func (s *rpcSession) AddReqNum(num int32) {
-//	atomic.AddInt32(&s.reqNum, num)
-//}
-//
-//func (s *rpcSession) GetReqNum() int32 {
-//	return atomic.LoadInt32(&s.reqNum)
-//}
-//
-//// //////////////////////////////////////////
-//// RpcClientHandler
-//// //////////////////////////////////////////
-//
-//// RpcClientHandler ...
-//type RpcClientHandler struct {
-//	conn *gettyRPCClient
-//}
-//
-//// NewRpcClientHandler ...
-//func NewRpcClientHandler(client *gettyRPCClient) *RpcClientHandler {
-//	return &RpcClientHandler{conn: client}
-//}
-//
-//// OnOpen ...
-//func (h *RpcClientHandler) OnOpen(session getty.Session) error {
-//	h.conn.addSession(session)
-//	return nil
-//}
-//
-//// OnError ...
-//func (h *RpcClientHandler) OnError(session getty.Session, err error) {
-//	logger.Infof("session{%s} got error{%v}, will be closed.", session.Stat(), err)
-//	h.conn.removeSession(session)
-//}
-//
-//// OnClose ...
-//func (h *RpcClientHandler) OnClose(session getty.Session) {
-//	logger.Infof("session{%s} is closing......", session.Stat())
-//	h.conn.removeSession(session)
-//}
-//
-//// OnMessage ...
-//func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) {
-//	p, ok := pkg.(*DubboPackage)
-//	if !ok {
-//		logger.Errorf("illegal package")
-//		return
-//	}
-//
-//	if p.Header.Type&hessian.PackageHeartbeat != 0x00 {
-//		if p.Header.Type&hessian.PackageResponse != 0x00 {
-//			logger.Debugf("get rpc heartbeat response{header: %#v, body: %#v}", p.Header, p.Body)
-//			if p.Err != nil {
-//				logger.Errorf("rpc heartbeat response{error: %#v}", p.Err)
-//			}
-//			h.conn.pool.rpcClient.removePendingResponse(SequenceType(p.Header.ID))
-//		} else {
-//			logger.Debugf("get rpc heartbeat request{header: %#v, service: %#v, body: %#v}", p.Header, p.Service, p.Body)
-//			p.Header.ResponseStatus = hessian.Response_OK
-//			reply(session, p, hessian.PackageHeartbeat)
-//		}
-//		return
-//	}
-//	logger.Debugf("get rpc response{header: %#v, body: %#v}", p.Header, p.Body)
-//
-//	h.conn.updateSession(session)
-//
-//	pendingResponse := h.conn.pool.rpcClient.removePendingResponse(SequenceType(p.Header.ID))
-//	if pendingResponse == nil {
-//		logger.Errorf("failed to get pending response context for response package %s", *p)
-//		return
-//	}
-//
-//	if p.Err != nil {
-//		pendingResponse.err = p.Err
-//	}
-//
-//	pendingResponse.response.atta = p.Body.(*Response).atta
-//
-//	if pendingResponse.callback == nil {
-//		pendingResponse.done <- struct{}{}
-//	} else {
-//		pendingResponse.callback(pendingResponse.GetCallResponse())
-//	}
-//}
-//
-//// OnCron ...
-//func (h *RpcClientHandler) OnCron(session getty.Session) {
-//	rpcSession, err := h.conn.getClientRpcSession(session)
-//	if err != nil {
-//		logger.Errorf("client.getClientSession(session{%s}) = error{%v}",
-//			session.Stat(), perrors.WithStack(err))
-//		return
-//	}
-//	if h.conn.pool.rpcClient.conf.sessionTimeout.Nanoseconds() < time.Since(session.GetActive()).Nanoseconds() {
-//		logger.Warnf("session{%s} timeout{%s}, reqNum{%d}",
-//			session.Stat(), time.Since(session.GetActive()).String(), rpcSession.reqNum)
-//		h.conn.removeSession(session) // -> h.conn.close() -> h.conn.pool.remove(h.conn)
-//		return
-//	}
-//
-//	h.conn.pool.rpcClient.heartbeat(session)
-//}
-//
-//// //////////////////////////////////////////
-//// RpcServerHandler
-//// //////////////////////////////////////////
-//
-//// RpcServerHandler ...
-//type RpcServerHandler struct {
-//	maxSessionNum  int
-//	sessionTimeout time.Duration
-//	sessionMap     map[getty.Session]*rpcSession
-//	rwlock         sync.RWMutex
-//}
-//
-//// NewRpcServerHandler ...
-//func NewRpcServerHandler(maxSessionNum int, sessionTimeout time.Duration) *RpcServerHandler {
-//	return &RpcServerHandler{
-//		maxSessionNum:  maxSessionNum,
-//		sessionTimeout: sessionTimeout,
-//		sessionMap:     make(map[getty.Session]*rpcSession),
-//	}
-//}
-//
-//// OnOpen ...
-//func (h *RpcServerHandler) OnOpen(session getty.Session) error {
-//	var err error
-//	h.rwlock.RLock()
-//	if h.maxSessionNum <= len(h.sessionMap) {
-//		err = errTooManySessions
-//	}
-//	h.rwlock.RUnlock()
-//	if err != nil {
-//		return perrors.WithStack(err)
-//	}
-//
-//	logger.Infof("got session:%s", session.Stat())
-//	h.rwlock.Lock()
-//	h.sessionMap[session] = &rpcSession{session: session}
-//	h.rwlock.Unlock()
-//	return nil
-//}
-//
-//// OnError ...
-//func (h *RpcServerHandler) OnError(session getty.Session, err error) {
-//	logger.Infof("session{%s} got error{%v}, will be closed.", session.Stat(), err)
-//	h.rwlock.Lock()
-//	delete(h.sessionMap, session)
-//	h.rwlock.Unlock()
-//}
-//
-//// OnClose ...
-//func (h *RpcServerHandler) OnClose(session getty.Session) {
-//	logger.Infof("session{%s} is closing......", session.Stat())
-//	h.rwlock.Lock()
-//	delete(h.sessionMap, session)
-//	h.rwlock.Unlock()
-//}
-//
-//// OnMessage ...
-//func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) {
-//	h.rwlock.Lock()
-//	if _, ok := h.sessionMap[session]; ok {
-//		h.sessionMap[session].reqNum++
-//	}
-//	h.rwlock.Unlock()
-//
-//	p, ok := pkg.(*DubboPackage)
-//	if !ok {
-//		logger.Errorf("illegal package{%#v}", pkg)
-//		return
-//	}
-//	p.Header.ResponseStatus = hessian.Response_OK
-//
-//	// heartbeat
-//	if p.Header.Type&hessian.PackageHeartbeat != 0x00 {
-//		logger.Debugf("get rpc heartbeat request{header: %#v, service: %#v, body: %#v}", p.Header, p.Service, p.Body)
-//		reply(session, p, hessian.PackageHeartbeat)
-//		return
-//	}
-//
-//	twoway := true
-//	// not twoway
-//	if p.Header.Type&hessian.PackageRequest_TwoWay == 0x00 {
-//		twoway = false
-//	}
-//
-//	defer func() {
-//		if e := recover(); e != nil {
-//			p.Header.ResponseStatus = hessian.Response_SERVER_ERROR
-//			if err, ok := e.(error); ok {
-//				logger.Errorf("OnMessage panic: %+v", perrors.WithStack(err))
-//				p.Body = perrors.WithStack(err)
-//			} else if err, ok := e.(string); ok {
-//				logger.Errorf("OnMessage panic: %+v", perrors.New(err))
-//				p.Body = perrors.New(err)
-//			} else {
-//				logger.Errorf("OnMessage panic: %+v, this is impossible.", e)
-//				p.Body = e
-//			}
-//
-//			if !twoway {
-//				return
-//			}
-//			reply(session, p, hessian.PackageResponse)
-//		}
-//
-//	}()
-//
-//	u := common.NewURLWithOptions(common.WithPath(p.Service.Path), common.WithParams(url.Values{}),
-//		common.WithParamsValue(constant.GROUP_KEY, p.Service.Group),
-//		common.WithParamsValue(constant.INTERFACE_KEY, p.Service.Interface),
-//		common.WithParamsValue(constant.VERSION_KEY, p.Service.Version))
-//	exporter, _ := dubboProtocol.ExporterMap().Load(u.ServiceKey())
-//	if exporter == nil {
-//		err := fmt.Errorf("don't have this exporter, key: %s", u.ServiceKey())
-//		logger.Errorf(err.Error())
-//		p.Header.ResponseStatus = hessian.Response_OK
-//		p.Body = err
-//		reply(session, p, hessian.PackageResponse)
-//		return
-//	}
-//	invoker := exporter.(protocol.Exporter).GetInvoker()
-//	if invoker != nil {
-//		attachments := p.Body.(map[string]interface{})["attachments"].(map[string]string)
-//		attachments[constant.LOCAL_ADDR] = session.LocalAddr()
-//		attachments[constant.REMOTE_ADDR] = session.RemoteAddr()
-//
-//		args := p.Body.(map[string]interface{})["args"].([]interface{})
-//		inv := invocation.NewRPCInvocation(p.Service.Method, args, attachments)
-//
-//		ctx := rebuildCtx(inv)
-//
-//		result := invoker.Invoke(ctx, inv)
-//		if err := result.Error(); err != nil {
-//			p.Header.ResponseStatus = hessian.Response_OK
-//			p.Body = hessian.NewResponse(nil, err, result.Attachments())
-//		} else {
-//			res := result.Result()
-//			p.Header.ResponseStatus = hessian.Response_OK
-//			p.Body = hessian.NewResponse(res, nil, result.Attachments())
-//		}
-//	}
-//
-//	if !twoway {
-//		return
-//	}
-//	reply(session, p, hessian.PackageResponse)
-//}
-//
-//// OnCron ...
-//func (h *RpcServerHandler) OnCron(session getty.Session) {
-//	var (
-//		flag   bool
-//		active time.Time
-//	)
-//
-//	h.rwlock.RLock()
-//	if _, ok := h.sessionMap[session]; ok {
-//		active = session.GetActive()
-//		if h.sessionTimeout.Nanoseconds() < time.Since(active).Nanoseconds() {
-//			flag = true
-//			logger.Warnf("session{%s} timeout{%s}, reqNum{%d}",
-//				session.Stat(), time.Since(active).String(), h.sessionMap[session].reqNum)
-//		}
-//	}
-//	h.rwlock.RUnlock()
-//
-//	if flag {
-//		h.rwlock.Lock()
-//		delete(h.sessionMap, session)
-//		h.rwlock.Unlock()
-//		session.Close()
-//	}
-//}
-//
-//// rebuildCtx rebuild the context by attachment.
-//// Once we decided to transfer more context's key-value, we should change this.
-//// now we only support rebuild the tracing context
-//func rebuildCtx(inv *invocation.RPCInvocation) context.Context {
-//	ctx := context.Background()
-//
-//	// actually, if user do not use any opentracing framework, the err will not be nil.
-//	spanCtx, err := opentracing.GlobalTracer().Extract(opentracing.TextMap,
-//		opentracing.TextMapCarrier(inv.Attachments()))
-//	if err == nil {
-//		ctx = context.WithValue(ctx, constant.TRACING_REMOTE_SPAN_CTX, spanCtx)
-//	}
-//	return ctx
-//}
-//
-//func reply(session getty.Session, req *DubboPackage, tp hessian.PackageType) {
-//	resp := &DubboPackage{
-//		Header: hessian.DubboHeader{
-//			SerialID:       req.Header.SerialID,
-//			Type:           tp,
-//			ID:             req.Header.ID,
-//			ResponseStatus: req.Header.ResponseStatus,
-//		},
-//	}
-//
-//	if req.Header.Type&hessian.PackageRequest != 0x00 {
-//		resp.Body = req.Body
-//	} else {
-//		resp.Body = nil
-//	}
-//
-//	if err := session.WritePkg(resp, WritePkg_Timeout); err != nil {
-//		logger.Errorf("WritePkg error: %#v, %#v", perrors.WithStack(err), req.Header)
-//	}
-//}
diff --git a/protocol/dubbo/listener_test.go b/protocol/dubbo/listener_test.go
deleted file mode 100644
index 1057dbfa368a4abbbbba86532f055f44c0e2f8ba..0000000000000000000000000000000000000000
--- a/protocol/dubbo/listener_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"testing"
-//)
-//
-//import (
-//	"github.com/opentracing/opentracing-go"
-//	"github.com/opentracing/opentracing-go/mocktracer"
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common/constant"
-//	"github.com/apache/dubbo-go/protocol/invocation"
-//)
-//
-//// test rebuild the ctx
-//func TestRebuildCtx(t *testing.T) {
-//	opentracing.SetGlobalTracer(mocktracer.New())
-//	attach := make(map[string]string, 10)
-//	attach[constant.VERSION_KEY] = "1.0"
-//	attach[constant.GROUP_KEY] = "MyGroup"
-//	inv := invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
-//
-//	// attachment doesn't contains any tracing key-value pair,
-//	ctx := rebuildCtx(inv)
-//	assert.NotNil(t, ctx)
-//	assert.Nil(t, ctx.Value(constant.TRACING_REMOTE_SPAN_CTX))
-//
-//	span, ctx := opentracing.StartSpanFromContext(ctx, "Test-Client")
-//
-//	opentracing.GlobalTracer().Inject(span.Context(), opentracing.TextMap,
-//		opentracing.TextMapCarrier(inv.Attachments()))
-//	// rebuild the context success
-//	inv = invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
-//	ctx = rebuildCtx(inv)
-//	span.Finish()
-//	assert.NotNil(t, ctx)
-//	assert.NotNil(t, ctx.Value(constant.TRACING_REMOTE_SPAN_CTX))
-//}
diff --git a/protocol/dubbo/pool.go b/protocol/dubbo/pool.go
deleted file mode 100644
index 3dda895d55cfbfba12666c0f64e6088cf3929335..0000000000000000000000000000000000000000
--- a/protocol/dubbo/pool.go
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"fmt"
-//	"math/rand"
-//	"net"
-//	"sync"
-//	"sync/atomic"
-//	"time"
-//)
-//
-//import (
-//	"github.com/dubbogo/getty"
-//	perrors "github.com/pkg/errors"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common/logger"
-//)
-//
-//type gettyRPCClient struct {
-//	once     sync.Once
-//	protocol string
-//	addr     string
-//	active   int64 // zero, not create or be destroyed
-//
-//	pool *gettyRPCClientPool
-//
-//	lock        sync.RWMutex
-//	gettyClient getty.Client
-//	sessions    []*rpcSession
-//}
-//
-//var (
-//	errClientPoolClosed = perrors.New("client pool closed")
-//)
-//
-//func newGettyRPCClientConn(pool *gettyRPCClientPool, protocol, addr string) (*gettyRPCClient, error) {
-//	c := &gettyRPCClient{
-//		protocol: protocol,
-//		addr:     addr,
-//		pool:     pool,
-//		gettyClient: getty.NewTCPClient(
-//			getty.WithServerAddress(addr),
-//			getty.WithConnectionNumber((int)(pool.rpcClient.conf.ConnectionNum)),
-//			getty.WithReconnectInterval(pool.rpcClient.conf.ReconnectInterval),
-//		),
-//	}
-//	go c.gettyClient.RunEventLoop(c.newSession)
-//	idx := 1
-//	times := int(pool.rpcClient.opts.ConnectTimeout / 1e6)
-//	for {
-//		idx++
-//		if c.isAvailable() {
-//			break
-//		}
-//
-//		if idx > times {
-//			c.gettyClient.Close()
-//			return nil, perrors.New(fmt.Sprintf("failed to create client connection to %s in %f seconds", addr, float32(times)/1000))
-//		}
-//		time.Sleep(1e6)
-//	}
-//	logger.Debug("client init ok")
-//	c.updateActive(time.Now().Unix())
-//
-//	return c, nil
-//}
-//
-//func (c *gettyRPCClient) updateActive(active int64) {
-//	atomic.StoreInt64(&c.active, active)
-//}
-//
-//func (c *gettyRPCClient) getActive() int64 {
-//	return atomic.LoadInt64(&c.active)
-//}
-//
-//func (c *gettyRPCClient) newSession(session getty.Session) error {
-//	var (
-//		ok      bool
-//		tcpConn *net.TCPConn
-//		conf    ClientConfig
-//	)
-//
-//	conf = c.pool.rpcClient.conf
-//	if conf.GettySessionParam.CompressEncoding {
-//		session.SetCompressType(getty.CompressZip)
-//	}
-//
-//	if tcpConn, ok = session.Conn().(*net.TCPConn); !ok {
-//		panic(fmt.Sprintf("%s, session.conn{%#v} is not tcp connection\n", session.Stat(), session.Conn()))
-//	}
-//
-//	tcpConn.SetNoDelay(conf.GettySessionParam.TcpNoDelay)
-//	tcpConn.SetKeepAlive(conf.GettySessionParam.TcpKeepAlive)
-//	if conf.GettySessionParam.TcpKeepAlive {
-//		tcpConn.SetKeepAlivePeriod(conf.GettySessionParam.keepAlivePeriod)
-//	}
-//	tcpConn.SetReadBuffer(conf.GettySessionParam.TcpRBufSize)
-//	tcpConn.SetWriteBuffer(conf.GettySessionParam.TcpWBufSize)
-//
-//	session.SetName(conf.GettySessionParam.SessionName)
-//	session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen)
-//	session.SetPkgHandler(NewRpcClientPackageHandler(c.pool.rpcClient))
-//	session.SetEventListener(NewRpcClientHandler(c))
-//	session.SetWQLen(conf.GettySessionParam.PkgWQSize)
-//	session.SetReadTimeout(conf.GettySessionParam.tcpReadTimeout)
-//	session.SetWriteTimeout(conf.GettySessionParam.tcpWriteTimeout)
-//	session.SetCronPeriod((int)(conf.heartbeatPeriod.Nanoseconds() / 1e6))
-//	session.SetWaitTime(conf.GettySessionParam.waitTimeout)
-//	logger.Debugf("client new session:%s\n", session.Stat())
-//
-//	session.SetTaskPool(clientGrpool)
-//
-//	return nil
-//}
-//
-//func (c *gettyRPCClient) selectSession() getty.Session {
-//	c.lock.RLock()
-//	defer c.lock.RUnlock()
-//
-//	if c.sessions == nil {
-//		return nil
-//	}
-//
-//	count := len(c.sessions)
-//	if count == 0 {
-//		return nil
-//	}
-//	return c.sessions[rand.Int31n(int32(count))].session
-//}
-//
-//func (c *gettyRPCClient) addSession(session getty.Session) {
-//	logger.Debugf("add session{%s}", session.Stat())
-//	if session == nil {
-//		return
-//	}
-//
-//	c.lock.Lock()
-//	defer c.lock.Unlock()
-//	if c.sessions == nil {
-//		c.sessions = make([]*rpcSession, 0, 16)
-//	}
-//	c.sessions = append(c.sessions, &rpcSession{session: session})
-//}
-//
-//func (c *gettyRPCClient) removeSession(session getty.Session) {
-//	if session == nil {
-//		return
-//	}
-//
-//	var removeFlag bool
-//	func() {
-//		c.lock.Lock()
-//		defer c.lock.Unlock()
-//		if c.sessions == nil {
-//			return
-//		}
-//
-//		for i, s := range c.sessions {
-//			if s.session == session {
-//				c.sessions = append(c.sessions[:i], c.sessions[i+1:]...)
-//				logger.Debugf("delete session{%s}, its index{%d}", session.Stat(), i)
-//				break
-//			}
-//		}
-//		logger.Infof("after remove session{%s}, left session number:%d", session.Stat(), len(c.sessions))
-//		if len(c.sessions) == 0 {
-//			removeFlag = true
-//		}
-//	}()
-//	if removeFlag {
-//		c.pool.safeRemove(c)
-//		c.close()
-//	}
-//}
-//
-//func (c *gettyRPCClient) updateSession(session getty.Session) {
-//	if session == nil {
-//		return
-//	}
-//
-//	var rs *rpcSession
-//	func() {
-//		c.lock.RLock()
-//		defer c.lock.RUnlock()
-//		if c.sessions == nil {
-//			return
-//		}
-//
-//		for i, s := range c.sessions {
-//			if s.session == session {
-//				rs = c.sessions[i]
-//				break
-//			}
-//		}
-//	}()
-//	if rs != nil {
-//		rs.AddReqNum(1)
-//	}
-//}
-//
-//func (c *gettyRPCClient) getClientRpcSession(session getty.Session) (rpcSession, error) {
-//	var (
-//		err        error
-//		rpcSession rpcSession
-//	)
-//	c.lock.RLock()
-//	defer c.lock.RUnlock()
-//	if c.sessions == nil {
-//		return rpcSession, errClientClosed
-//	}
-//
-//	err = errSessionNotExist
-//	for _, s := range c.sessions {
-//		if s.session == session {
-//			rpcSession = *s
-//			err = nil
-//			break
-//		}
-//	}
-//
-//	return rpcSession, perrors.WithStack(err)
-//}
-//
-//func (c *gettyRPCClient) isAvailable() bool {
-//	if c.selectSession() == nil {
-//		return false
-//	}
-//
-//	return true
-//}
-//
-//func (c *gettyRPCClient) close() error {
-//	closeErr := perrors.Errorf("close gettyRPCClient{%#v} again", c)
-//	c.once.Do(func() {
-//		var (
-//			gettyClient getty.Client
-//			sessions    []*rpcSession
-//		)
-//		func() {
-//			c.lock.Lock()
-//			defer c.lock.Unlock()
-//
-//			gettyClient = c.gettyClient
-//			c.gettyClient = nil
-//
-//			sessions = make([]*rpcSession, 0, len(c.sessions))
-//			for _, s := range c.sessions {
-//				sessions = append(sessions, s)
-//			}
-//			c.sessions = c.sessions[:0]
-//		}()
-//
-//		c.updateActive(0)
-//
-//		go func() {
-//			if gettyClient != nil {
-//				gettyClient.Close()
-//			}
-//			for _, s := range sessions {
-//				logger.Infof("close client session{%s, last active:%s, request number:%d}",
-//					s.session.Stat(), s.session.GetActive().String(), s.GetReqNum())
-//				s.session.Close()
-//			}
-//		}()
-//
-//		closeErr = nil
-//	})
-//	return closeErr
-//}
-//
-//type gettyRPCClientPool struct {
-//	rpcClient *Client
-//	size      int   // size of []*gettyRPCClient
-//	ttl       int64 // ttl of every gettyRPCClient, it is checked when getConn
-//
-//	sync.Mutex
-//	conns []*gettyRPCClient
-//}
-//
-//func newGettyRPCClientConnPool(rpcClient *Client, size int, ttl time.Duration) *gettyRPCClientPool {
-//	return &gettyRPCClientPool{
-//		rpcClient: rpcClient,
-//		size:      size,
-//		ttl:       int64(ttl.Seconds()),
-//		conns:     make([]*gettyRPCClient, 0, 16),
-//	}
-//}
-//
-//func (p *gettyRPCClientPool) close() {
-//	p.Lock()
-//	conns := p.conns
-//	p.conns = nil
-//	p.Unlock()
-//	for _, conn := range conns {
-//		conn.close()
-//	}
-//}
-//
-//func (p *gettyRPCClientPool) getGettyRpcClient(protocol, addr string) (*gettyRPCClient, error) {
-//	conn, err := p.get()
-//	if err == nil && conn == nil {
-//		// create new conn
-//		rpcClientConn, err := newGettyRPCClientConn(p, protocol, addr)
-//		return rpcClientConn, perrors.WithStack(err)
-//	}
-//	return conn, perrors.WithStack(err)
-//}
-//
-//func (p *gettyRPCClientPool) get() (*gettyRPCClient, error) {
-//	now := time.Now().Unix()
-//
-//	p.Lock()
-//	defer p.Unlock()
-//	if p.conns == nil {
-//		return nil, errClientPoolClosed
-//	}
-//
-//	for len(p.conns) > 0 {
-//		conn := p.conns[len(p.conns)-1]
-//		p.conns = p.conns[:len(p.conns)-1]
-//
-//		if d := now - conn.getActive(); d > p.ttl {
-//			p.remove(conn)
-//			go conn.close()
-//			continue
-//		}
-//		conn.updateActive(now) //update active time
-//		return conn, nil
-//	}
-//	return nil, nil
-//}
-//
-//func (p *gettyRPCClientPool) put(conn *gettyRPCClient) {
-//	if conn == nil || conn.getActive() == 0 {
-//		return
-//	}
-//
-//	p.Lock()
-//	defer p.Unlock()
-//
-//	if p.conns == nil {
-//		return
-//	}
-//
-//	// check whether @conn has existed in p.conns or not.
-//	for i := range p.conns {
-//		if p.conns[i] == conn {
-//			return
-//		}
-//	}
-//
-//	if len(p.conns) >= p.size {
-//		// delete @conn from client pool
-//		// p.remove(conn)
-//		conn.close()
-//		return
-//	}
-//	p.conns = append(p.conns, conn)
-//}
-//
-//func (p *gettyRPCClientPool) remove(conn *gettyRPCClient) {
-//	if conn == nil || conn.getActive() == 0 {
-//		return
-//	}
-//
-//	if p.conns == nil {
-//		return
-//	}
-//
-//	if len(p.conns) > 0 {
-//		for idx, c := range p.conns {
-//			if conn == c {
-//				p.conns = append(p.conns[:idx], p.conns[idx+1:]...)
-//				break
-//			}
-//		}
-//	}
-//}
-//
-//func (p *gettyRPCClientPool) safeRemove(conn *gettyRPCClient) {
-//	p.Lock()
-//	defer p.Unlock()
-//
-//	p.remove(conn)
-//}
diff --git a/protocol/dubbo/readwriter.go b/protocol/dubbo/readwriter.go
deleted file mode 100644
index 00b79e47f378c5cfd94a88d39338f521c1caf2d1..0000000000000000000000000000000000000000
--- a/protocol/dubbo/readwriter.go
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"bytes"
-//	"reflect"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go-hessian2"
-//	"github.com/dubbogo/getty"
-//	perrors "github.com/pkg/errors"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/constant"
-//	"github.com/apache/dubbo-go/common/logger"
-//)
-//
-//////////////////////////////////////////////
-//// RpcClientPackageHandler
-//////////////////////////////////////////////
-//
-//// RpcClientPackageHandler ...
-//type RpcClientPackageHandler struct {
-//	client *Client
-//}
-//
-//// NewRpcClientPackageHandler ...
-//func NewRpcClientPackageHandler(client *Client) *RpcClientPackageHandler {
-//	return &RpcClientPackageHandler{client: client}
-//}
-//
-//func (p *RpcClientPackageHandler) Read(ss getty.Session, data []byte) (interface{}, int, error) {
-//	pkg := &DubboPackage{}
-//
-//	buf := bytes.NewBuffer(data)
-//	err := pkg.Unmarshal(buf, p.client)
-//	if err != nil {
-//		originErr := perrors.Cause(err)
-//		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
-//			return nil, 0, nil
-//		}
-//
-//		logger.Errorf("pkg.Unmarshal(ss:%+v, len(@data):%d) = error:%+v", ss, len(data), err)
-//
-//		return nil, 0, perrors.WithStack(err)
-//	}
-//
-//	if pkg.Header.Type&hessian.PackageRequest == 0x00 {
-//		pkg.Err = pkg.Body.(*hessian.Response).Exception
-//		pkg.Body = NewResponse(pkg.Body.(*hessian.Response).RspObj, pkg.Body.(*hessian.Response).Attachments)
-//	}
-//
-//	return pkg, hessian.HEADER_LENGTH + pkg.Header.BodyLen, nil
-//}
-//
-//func (p *RpcClientPackageHandler) Write(ss getty.Session, pkg interface{}) ([]byte, error) {
-//	req, ok := pkg.(*DubboPackage)
-//	if !ok {
-//		logger.Errorf("illegal pkg:%+v\n", pkg)
-//		return nil, perrors.New("invalid rpc request")
-//	}
-//
-//	buf, err := req.Marshal()
-//	if err != nil {
-//		logger.Warnf("binary.Write(req{%#v}) = err{%#v}", req, perrors.WithStack(err))
-//		return nil, perrors.WithStack(err)
-//	}
-//
-//	return buf.Bytes(), nil
-//}
-//
-//////////////////////////////////////////////
-//// RpcServerPackageHandler
-//////////////////////////////////////////////
-//
-//var (
-//	rpcServerPkgHandler = &RpcServerPackageHandler{}
-//)
-//
-//// RpcServerPackageHandler ...
-//type RpcServerPackageHandler struct{}
-//
-//func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface{}, int, error) {
-//	pkg := &DubboPackage{
-//		Body: make([]interface{}, 7),
-//	}
-//
-//	buf := bytes.NewBuffer(data)
-//	err := pkg.Unmarshal(buf)
-//	if err != nil {
-//		originErr := perrors.Cause(err)
-//		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
-//			return nil, 0, nil
-//		}
-//
-//		logger.Errorf("pkg.Unmarshal(ss:%+v, len(@data):%d) = error:%+v", ss, len(data), err)
-//
-//		return nil, 0, perrors.WithStack(err)
-//	}
-//
-//	if pkg.Header.Type&hessian.PackageHeartbeat == 0x00 {
-//		// convert params of request
-//		req := pkg.Body.([]interface{}) // length of body should be 7
-//		if len(req) > 0 {
-//			var dubboVersion, argsTypes string
-//			var args []interface{}
-//			var attachments map[string]string
-//			if req[0] != nil {
-//				dubboVersion = req[0].(string)
-//			}
-//			if req[1] != nil {
-//				pkg.Service.Path = req[1].(string)
-//			}
-//			if req[2] != nil {
-//				pkg.Service.Version = req[2].(string)
-//			}
-//			if req[3] != nil {
-//				pkg.Service.Method = req[3].(string)
-//			}
-//			if req[4] != nil {
-//				argsTypes = req[4].(string)
-//			}
-//			if req[5] != nil {
-//				args = req[5].([]interface{})
-//			}
-//			if req[6] != nil {
-//				attachments = req[6].(map[string]string)
-//			}
-//			if pkg.Service.Path == "" && len(attachments[constant.PATH_KEY]) > 0 {
-//				pkg.Service.Path = attachments[constant.PATH_KEY]
-//			}
-//			if _, ok := attachments[constant.INTERFACE_KEY]; ok {
-//				pkg.Service.Interface = attachments[constant.INTERFACE_KEY]
-//			} else {
-//				pkg.Service.Interface = pkg.Service.Path
-//			}
-//			if len(attachments[constant.GROUP_KEY]) > 0 {
-//				pkg.Service.Group = attachments[constant.GROUP_KEY]
-//			}
-//			pkg.Body = map[string]interface{}{
-//				"dubboVersion": dubboVersion,
-//				"argsTypes":    argsTypes,
-//				"args":         args,
-//				"service":      common.ServiceMap.GetService(DUBBO, pkg.Service.Path), // path as a key
-//				"attachments":  attachments,
-//			}
-//		}
-//	}
-//
-//	return pkg, hessian.HEADER_LENGTH + pkg.Header.BodyLen, nil
-//}
-//
-//func (p *RpcServerPackageHandler) Write(ss getty.Session, pkg interface{}) ([]byte, error) {
-//	res, ok := pkg.(*DubboPackage)
-//	if !ok {
-//		logger.Errorf("illegal pkg:%+v\n, it is %+v", pkg, reflect.TypeOf(pkg))
-//		return nil, perrors.New("invalid rpc response")
-//	}
-//
-//	buf, err := res.Marshal()
-//	if err != nil {
-//		logger.Warnf("binary.Write(res{%#v}) = err{%#v}", res, perrors.WithStack(err))
-//		return nil, perrors.WithStack(err)
-//	}
-//
-//	return buf.Bytes(), nil
-//}
diff --git a/protocol/dubbo/server.go b/protocol/dubbo/server.go
deleted file mode 100644
index 35a162cc37be441a2281ae71d89fb371bda2636a..0000000000000000000000000000000000000000
--- a/protocol/dubbo/server.go
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dubbo
-//
-//import (
-//	"fmt"
-//	"net"
-//)
-//
-//import (
-//	"github.com/dubbogo/getty"
-//	"github.com/dubbogo/gost/sync"
-//	"gopkg.in/yaml.v2"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/logger"
-//	"github.com/apache/dubbo-go/config"
-//)
-//
-//var (
-//	srvConf   *ServerConfig
-//	srvGrpool *gxsync.TaskPool
-//)
-//
-//func init() {
-//
-//	// load clientconfig from provider_config
-//	// default use dubbo
-//	providerConfig := config.GetProviderConfig()
-//	if providerConfig.ApplicationConfig == nil {
-//		return
-//	}
-//	protocolConf := providerConfig.ProtocolConf
-//	defaultServerConfig := GetDefaultServerConfig()
-//	if protocolConf == nil {
-//		logger.Info("protocol_conf default use dubbo config")
-//	} else {
-//		dubboConf := protocolConf.(map[interface{}]interface{})[DUBBO]
-//		if dubboConf == nil {
-//			logger.Warnf("dubboConf is nil")
-//			return
-//		}
-//
-//		dubboConfByte, err := yaml.Marshal(dubboConf)
-//		if err != nil {
-//			panic(err)
-//		}
-//		err = yaml.Unmarshal(dubboConfByte, &defaultServerConfig)
-//		if err != nil {
-//			panic(err)
-//		}
-//	}
-//	srvConf = &defaultServerConfig
-//	if err := srvConf.CheckValidity(); err != nil {
-//		panic(err)
-//	}
-//	SetServerGrpool()
-//}
-//
-//// SetServerConfig ...
-//func SetServerConfig(s ServerConfig) {
-//	srvConf = &s
-//	err := srvConf.CheckValidity()
-//	if err != nil {
-//		logger.Warnf("[ServerConfig CheckValidity] error: %v", err)
-//		return
-//	}
-//	SetServerGrpool()
-//}
-//
-//// GetServerConfig ...
-//func GetServerConfig() ServerConfig {
-//	return *srvConf
-//}
-//
-//// SetServerGrpool ...
-//func SetServerGrpool() {
-//	if srvConf.GrPoolSize > 1 {
-//		srvGrpool = gxsync.NewTaskPool(gxsync.WithTaskPoolTaskPoolSize(srvConf.GrPoolSize), gxsync.WithTaskPoolTaskQueueLength(srvConf.QueueLen),
-//			gxsync.WithTaskPoolTaskQueueNumber(srvConf.QueueNumber))
-//	}
-//}
-//
-//// Server ...
-//type Server struct {
-//	conf       ServerConfig
-//	tcpServer  getty.Server
-//	rpcHandler *RpcServerHandler
-//}
-//
-//// NewServer ...
-//func NewServer() *Server {
-//
-//	s := &Server{
-//		conf: *srvConf,
-//	}
-//
-//	s.rpcHandler = NewRpcServerHandler(s.conf.SessionNumber, s.conf.sessionTimeout)
-//
-//	return s
-//}
-//
-//func (s *Server) newSession(session getty.Session) error {
-//	var (
-//		ok      bool
-//		tcpConn *net.TCPConn
-//	)
-//	conf := s.conf
-//
-//	if conf.GettySessionParam.CompressEncoding {
-//		session.SetCompressType(getty.CompressZip)
-//	}
-//
-//	if tcpConn, ok = session.Conn().(*net.TCPConn); !ok {
-//		panic(fmt.Sprintf("%s, session.conn{%#v} is not tcp connection\n", session.Stat(), session.Conn()))
-//	}
-//
-//	tcpConn.SetNoDelay(conf.GettySessionParam.TcpNoDelay)
-//	tcpConn.SetKeepAlive(conf.GettySessionParam.TcpKeepAlive)
-//	if conf.GettySessionParam.TcpKeepAlive {
-//		tcpConn.SetKeepAlivePeriod(conf.GettySessionParam.keepAlivePeriod)
-//	}
-//	tcpConn.SetReadBuffer(conf.GettySessionParam.TcpRBufSize)
-//	tcpConn.SetWriteBuffer(conf.GettySessionParam.TcpWBufSize)
-//
-//	session.SetName(conf.GettySessionParam.SessionName)
-//	session.SetMaxMsgLen(conf.GettySessionParam.MaxMsgLen)
-//	session.SetPkgHandler(rpcServerPkgHandler)
-//	session.SetEventListener(s.rpcHandler)
-//	session.SetWQLen(conf.GettySessionParam.PkgWQSize)
-//	session.SetReadTimeout(conf.GettySessionParam.tcpReadTimeout)
-//	session.SetWriteTimeout(conf.GettySessionParam.tcpWriteTimeout)
-//	session.SetCronPeriod((int)(conf.sessionTimeout.Nanoseconds() / 1e6))
-//	session.SetWaitTime(conf.GettySessionParam.waitTimeout)
-//	logger.Debugf("app accepts new session:%s\n", session.Stat())
-//
-//	session.SetTaskPool(srvGrpool)
-//
-//	return nil
-//}
-//
-//// Start ...
-//func (s *Server) Start(url common.URL) {
-//	var (
-//		addr      string
-//		tcpServer getty.Server
-//	)
-//
-//	addr = url.Location
-//	tcpServer = getty.NewTCPServer(
-//		getty.WithLocalAddress(addr),
-//	)
-//	tcpServer.RunEventLoop(s.newSession)
-//	logger.Debugf("s bind addr{%s} ok!", addr)
-//	s.tcpServer = tcpServer
-//
-//}
-//
-//// Stop ...
-//func (s *Server) Stop() {
-//	s.tcpServer.Close()
-//}
diff --git a/remoting/codec.go b/remoting/codec.go
index 972a00d12b5bf0241cc994e18f16104fff618931..1c1e0257626801586e9445c4a0ac4aec6631d4d5 100644
--- a/remoting/codec.go
+++ b/remoting/codec.go
@@ -7,8 +7,12 @@ import (
 type Codec interface {
 	EncodeRequest(request *Request) (*bytes.Buffer, error)
 	EncodeResponse(response *Response) (*bytes.Buffer, error)
-	DecodeRequest(data []byte) (*Request, int, error)
-	DecodeResponse(data []byte) (*Response, int, error)
+	Decode(data []byte) (DecodeResult, int, error)
+}
+
+type DecodeResult struct {
+	IsRequest bool
+	Result    interface{}
 }
 
 var (
diff --git a/remoting/exchange.go b/remoting/exchange.go
index 498022926d0ee386f7b990db7ec414c83dd1b98c..eaa19f7195e205299217c5089b5cf012818d8155 100644
--- a/remoting/exchange.go
+++ b/remoting/exchange.go
@@ -1,9 +1,10 @@
 package remoting
 
 import (
+	"time"
+
 	"github.com/apache/dubbo-go/common"
 	"go.uber.org/atomic"
-	"time"
 )
 
 var (
@@ -88,7 +89,7 @@ type PendingResponse struct {
 	Err       error
 	start     time.Time
 	ReadStart time.Time
-	callback  common.AsyncCallback
+	Callback  common.AsyncCallback
 	response  *Response
 	Reply     interface{}
 	Done      chan struct{}
@@ -104,6 +105,10 @@ func NewPendingResponse(id int64) *PendingResponse {
 	}
 }
 
+func (r *PendingResponse) SetResponse(response *Response) {
+	r.response = response
+}
+
 // GetCallResponse ...
 func (r PendingResponse) GetCallResponse() common.CallbackResponse {
 	return AsyncCallbackResponse{
diff --git a/remoting/exchange_client.go b/remoting/exchange_client.go
index aff8bba22d2970f5f116c453dfac1da8750bd846..2a0e6cfd799f4b75de59b2dd8eed7a3426e66036 100644
--- a/remoting/exchange_client.go
+++ b/remoting/exchange_client.go
@@ -1,11 +1,12 @@
 package remoting
 
 import (
+	"sync"
+	"time"
+
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/logger"
 	"github.com/apache/dubbo-go/protocol"
-	"sync"
-	"time"
 )
 
 var (
@@ -24,9 +25,10 @@ type Client interface {
 	SetExchangeClient(client *ExchangeClient)
 	SetResponseHandler(responseHandler ResponseHandler)
 	//invoke once for connection
+	//ConfigClient()
 	Connect(url common.URL)
 	Close()
-	Request(request *Request, timeout time.Duration, callback common.AsyncCallback, response *PendingResponse) error
+	Request(request *Request, timeout time.Duration, response *PendingResponse) error
 }
 
 type ResponseHandler interface {
@@ -58,7 +60,7 @@ func (client *ExchangeClient) Request(invocation *protocol.Invocation, url commo
 	AddPendingResponse(rsp)
 	//rsp.callback = invo
 
-	err := client.client.Request(request, timeout, nil, rsp)
+	err := client.client.Request(request, timeout, rsp)
 	if err != nil {
 		result.Err = err
 		return err
@@ -77,11 +79,11 @@ func (client *ExchangeClient) AsyncRequest(invocation *protocol.Invocation, url
 
 	rsp := NewPendingResponse(request.Id)
 	rsp.response = NewResponse(request.Id, "2.0.2")
-	rsp.callback = callback
+	rsp.Callback = callback
 	rsp.Reply = (*invocation).Reply()
 	AddPendingResponse(rsp)
 
-	err := client.client.Request(request, timeout, nil, rsp)
+	err := client.client.Request(request, timeout, rsp)
 	if err != nil {
 		result.Err = err
 		return err
@@ -93,16 +95,15 @@ func (client *ExchangeClient) AsyncRequest(invocation *protocol.Invocation, url
 
 // oneway
 func (client *ExchangeClient) Send(invocation *protocol.Invocation, timeout time.Duration) error {
-	requestId := int64(SequenceId())
 	request := NewRequest("2.0.2")
 	request.Data = invocation
 	request.Event = false
 	request.TwoWay = false
 
 	rsp := NewPendingResponse(request.Id)
-	rsp.response = NewResponse(requestId, "2.0.2")
+	rsp.response = NewResponse(request.Id, "2.0.2")
 
-	err := client.client.Request(request, timeout, nil, rsp)
+	err := client.client.Request(request, timeout, rsp)
 	if err != nil {
 		return err
 	}
@@ -124,10 +125,11 @@ func (client *ExchangeClient) Handler(response *Response) {
 
 	pendingResponse.response = response
 
-	if pendingResponse.callback == nil {
+	if pendingResponse.Callback == nil {
+		pendingResponse.Err = pendingResponse.response.Error
 		pendingResponse.Done <- struct{}{}
 	} else {
-		pendingResponse.callback(pendingResponse.GetCallResponse())
+		pendingResponse.Callback(pendingResponse.GetCallResponse())
 	}
 }
 
diff --git a/remoting/getty/client.go b/remoting/getty/client.go
deleted file mode 100644
index b76033c6e9f13b33915c184f2af99f58baa36586..0000000000000000000000000000000000000000
--- a/remoting/getty/client.go
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package getty
-//
-//import (
-//	"github.com/apache/dubbo-go/remoting"
-//	"math/rand"
-//	"strings"
-//	"sync"
-//	"time"
-//)
-//
-//import (
-//	hessian "github.com/apache/dubbo-go-hessian2"
-//	"github.com/dubbogo/getty"
-//	gxsync "github.com/dubbogo/gost/sync"
-//	perrors "github.com/pkg/errors"
-//	"go.uber.org/atomic"
-//	"gopkg.in/yaml.v2"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/constant"
-//	"github.com/apache/dubbo-go/common/logger"
-//	"github.com/apache/dubbo-go/config"
-//)
-//
-//var (
-//	errInvalidCodecType  = perrors.New("illegal CodecType")
-//	errInvalidAddress    = perrors.New("remote address invalid or empty")
-//	errSessionNotExist   = perrors.New("session not exist")
-//	errClientClosed      = perrors.New("client closed")
-//	errClientReadTimeout = perrors.New("client read timeout")
-//
-//	clientConf   *ClientConfig
-//	clientGrpool *gxsync.TaskPool
-//)
-//
-//func init() {
-//
-//	// load clientconfig from consumer_config
-//	// default use dubbo
-//	consumerConfig := config.GetConsumerConfig()
-//	if consumerConfig.ApplicationConfig == nil {
-//		return
-//	}
-//	protocolConf := config.GetConsumerConfig().ProtocolConf
-//	defaultClientConfig := GetDefaultClientConfig()
-//	if protocolConf == nil {
-//		logger.Info("protocol_conf default use dubbo config")
-//	} else {
-//		dubboConf := protocolConf.(map[interface{}]interface{})[DUBBO]
-//		if dubboConf == nil {
-//			logger.Warnf("dubboConf is nil")
-//			return
-//		}
-//		dubboConfByte, err := yaml.Marshal(dubboConf)
-//		if err != nil {
-//			panic(err)
-//		}
-//		err = yaml.Unmarshal(dubboConfByte, &defaultClientConfig)
-//		if err != nil {
-//			panic(err)
-//		}
-//	}
-//	clientConf = &defaultClientConfig
-//	if err := clientConf.CheckValidity(); err != nil {
-//		logger.Warnf("[CheckValidity] error: %v", err)
-//		return
-//	}
-//	setClientGrpool()
-//
-//	rand.Seed(time.Now().UnixNano())
-//}
-//
-//// SetClientConf ...
-//func SetClientConf(c ClientConfig) {
-//	clientConf = &c
-//	err := clientConf.CheckValidity()
-//	if err != nil {
-//		logger.Warnf("[ClientConfig CheckValidity] error: %v", err)
-//		return
-//	}
-//	setClientGrpool()
-//}
-//
-//// GetClientConf ...
-//func GetClientConf() ClientConfig {
-//	return *clientConf
-//}
-//
-//func setClientGrpool() {
-//	if clientConf.GrPoolSize > 1 {
-//		clientGrpool = gxsync.NewTaskPool(gxsync.WithTaskPoolTaskPoolSize(clientConf.GrPoolSize), gxsync.WithTaskPoolTaskQueueLength(clientConf.QueueLen),
-//			gxsync.WithTaskPoolTaskQueueNumber(clientConf.QueueNumber))
-//	}
-//}
-//
-//// Options ...
-//type Options struct {
-//	// connect timeout
-//	ConnectTimeout time.Duration
-//	// request timeout
-//	RequestTimeout time.Duration
-//}
-//
-////AsyncCallbackResponse async response for dubbo
-//type AsyncCallbackResponse struct {
-//	common.CallbackResponse
-//	Opts      Options
-//	Cause     error
-//	Start     time.Time // invoke(call) start time == write start time
-//	ReadStart time.Time // read start time, write duration = ReadStart - Start
-//	Reply     interface{}
-//}
-//
-//// Client ...
-//type Client struct {
-//	opts     Options
-//	conf     ClientConfig
-//	pool     *gettyRPCClientPool
-//	sequence atomic.Uint64
-//
-//	pendingResponses *sync.Map
-//}
-//
-//// NewClient ...
-//func NewClient(opt Options) *Client {
-//
-//	switch {
-//	case opt.ConnectTimeout == 0:
-//		opt.ConnectTimeout = 3 * time.Second
-//		fallthrough
-//	case opt.RequestTimeout == 0:
-//		opt.RequestTimeout = 3 * time.Second
-//	}
-//
-//	// make sure that client request sequence is an odd number
-//	initSequence := uint64(rand.Int63n(time.Now().UnixNano()))
-//	if initSequence%2 == 0 {
-//		initSequence++
-//	}
-//
-//	c := &Client{
-//		opts:             opt,
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//	}
-//	c.sequence.Store(initSequence)
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	return c
-//}
-//
-////// Request ...
-////type Request struct {
-////	addr   string
-////	svcUrl common.URL
-////	method string
-////	args   interface{}
-////	atta   map[string]string
-////}
-////
-////// NewRequest ...
-////func NewRequest(addr string, svcUrl common.URL, method string, args interface{}, atta map[string]string) *Request {
-////	return &Request{
-////		addr:   addr,
-////		svcUrl: svcUrl,
-////		method: method,
-////		args:   args,
-////		atta:   atta,
-////	}
-////}
-////
-////// Response ...
-////type Response struct {
-////	reply interface{}
-////	atta  map[string]string
-////}
-////
-////// NewResponse ...
-////func NewResponse(reply interface{}, atta map[string]string) *Response {
-////	return &Response{
-////		reply: reply,
-////		atta:  atta,
-////	}
-////}
-//
-//// CallOneway call one way
-////func (c *Client) CallOneway(request *Request) error {
-////
-////	return perrors.WithStack(c.call(CT_OneWay, request, NewResponse(nil, nil), nil))
-////}
-////
-////// Call if @response is nil, the transport layer will get the response without notify the invoker.
-////func (c *Client) Call(request *Request, response *Response) error {
-////
-////	ct := CT_TwoWay
-////	if response.reply == nil {
-////		ct = CT_OneWay
-////	}
-////
-////	return perrors.WithStack(c.call(ct, request, response, nil))
-////}
-////
-////// AsyncCall ...
-////func (c *Client) AsyncCall(request *Request, callback common.AsyncCallback, response *Response) error {
-////
-////	return perrors.WithStack(c.call(CT_TwoWay, request, response, callback))
-////}
-//
-//func (c *Client) call(ct CallType, request *Request, response *Response, callback common.AsyncCallback) error {
-//
-//	p := &DubboPackage{}
-//	p.Service.Path = strings.TrimPrefix(request.svcUrl.Path, "/")
-//	p.Service.Interface = request.svcUrl.GetParam(constant.INTERFACE_KEY, "")
-//	p.Service.Version = request.svcUrl.GetParam(constant.VERSION_KEY, "")
-//	p.Service.Group = request.svcUrl.GetParam(constant.GROUP_KEY, "")
-//	p.Service.Method = request.method
-//
-//	p.Service.Timeout = c.opts.RequestTimeout
-//	var timeout = request.svcUrl.GetParam(strings.Join([]string{constant.METHOD_KEYS, request.method + constant.RETRIES_KEY}, "."), "")
-//	if len(timeout) != 0 {
-//		if t, err := time.ParseDuration(timeout); err == nil {
-//			p.Service.Timeout = t
-//		}
-//	}
-//
-//	p.Header.SerialID = byte(S_Dubbo)
-//	p.Body = hessian.NewRequest(request.args, request.atta)
-//
-//	var rsp *PendingResponse
-//	if ct != CT_OneWay {
-//		p.Header.Type = hessian.PackageRequest_TwoWay
-//		rsp = NewPendingResponse()
-//		rsp.response = response
-//		rsp.callback = callback
-//	} else {
-//		p.Header.Type = hessian.PackageRequest
-//	}
-//
-//	var (
-//		err     error
-//		session getty.Session
-//		conn    *gettyRPCClient
-//	)
-//	conn, session, err = c.selectSession(request.addr)
-//	if err != nil {
-//		return perrors.WithStack(err)
-//	}
-//	if session == nil {
-//		return errSessionNotExist
-//	}
-//	defer func() {
-//		if err == nil {
-//			c.pool.put(conn)
-//			return
-//		}
-//		conn.close()
-//	}()
-//
-//	if err = c.transfer(session, p, rsp); err != nil {
-//		return perrors.WithStack(err)
-//	}
-//
-//	if ct == CT_OneWay || callback != nil {
-//		return nil
-//	}
-//
-//	select {
-//	case <-getty.GetTimeWheel().After(c.opts.RequestTimeout):
-//		c.removePendingResponse(SequenceType(rsp.seq))
-//		return perrors.WithStack(errClientReadTimeout)
-//	case <-rsp.done:
-//		err = rsp.err
-//	}
-//
-//	return perrors.WithStack(err)
-//}
-//
-//// Close ...
-//func (c *Client) Close() {
-//	if c.pool != nil {
-//		c.pool.close()
-//	}
-//	c.pool = nil
-//}
-//
-//func (c *Client) selectSession(addr string) (*gettyRPCClient, getty.Session, error) {
-//	rpcClient, err := c.pool.getGettyRpcClient(DUBBO, addr)
-//	if err != nil {
-//		return nil, nil, perrors.WithStack(err)
-//	}
-//	return rpcClient, rpcClient.selectSession(), nil
-//}
-//
-//func (c *Client) heartbeat(session getty.Session) error {
-//	req := remoting.NewRequest("2.0.2")
-//	req.TwoWay = true
-//	req.Event = true
-//	resp := remoting.NewPendingResponse()
-//	return c.transfer(session, req, 3 * time.Second, resp)
-//}
-//
-//func (c *Client) transfer(session getty.Session, request *remoting.Request, timeout time.Duration,
-//	rsp *remoting.PendingResponse) error {
-//
-//	//sequence = c.sequence.Add(1)
-//	//
-//	//if pkg == nil {
-//	//	pkg = &DubboPackage{}
-//	//	pkg.Body = hessian.NewRequest([]interface{}{}, nil)
-//	//	pkg.Body = []interface{}{}
-//	//	pkg.Header.Type = hessian.PackageHeartbeat
-//	//	pkg.Header.SerialID = byte(S_Dubbo)
-//	//}
-//	//pkg.Header.ID = int64(sequence)
-//
-//	// cond1
-//	//if rsp != nil {
-//	//	c.addPendingResponse(rsp)
-//	//}
-//
-//	err := session.WritePkg(request, timeout)
-//	if rsp != nil { // cond2
-//		// cond2 should not merged with cond1. cause the response package may be returned very
-//		// soon and it will be handled by other goroutine.
-//		rsp.ReadStart = time.Now()
-//	}
-//
-//	return perrors.WithStack(err)
-//}
-//
-////
-////func (c *Client) addPendingResponse(pr *PendingResponse) {
-////	c.pendingResponses.Store(SequenceType(pr.seq), pr)
-////}
-////
-////func (c *Client) removePendingResponse(seq SequenceType) *PendingResponse {
-////	if c.pendingResponses == nil {
-////		return nil
-////	}
-////	if presp, ok := c.pendingResponses.Load(seq); ok {
-////		c.pendingResponses.Delete(seq)
-////		return presp.(*PendingResponse)
-////	}
-////	return nil
-////}
diff --git a/remoting/getty/client_test.go b/remoting/getty/client_test.go
deleted file mode 100644
index d0a4c97e47ed21d8518e6f817bc134f5b62342f3..0000000000000000000000000000000000000000
--- a/remoting/getty/client_test.go
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package getty
-//
-//import (
-//	"bytes"
-//	"context"
-//	"sync"
-//	"testing"
-//	"time"
-//)
-//
-//import (
-//	hessian "github.com/apache/dubbo-go-hessian2"
-//	perrors "github.com/pkg/errors"
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common"
-//	"github.com/apache/dubbo-go/common/proxy/proxy_factory"
-//	"github.com/apache/dubbo-go/protocol"
-//)
-//
-//func TestClient_CallOneway(t *testing.T) {
-//	proto, url := InitTest(t)
-//
-//	c := &Client{
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//		opts: Options{
-//			ConnectTimeout: 3e9,
-//			RequestTimeout: 6e9,
-//		},
-//	}
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	//user := &User{}
-//	err := c.CallOneway(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil))
-//	assert.NoError(t, err)
-//
-//	// destroy
-//	proto.Destroy()
-//}
-//
-//func TestClient_Call(t *testing.T) {
-//	proto, url := InitTest(t)
-//
-//	c := &Client{
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//		opts: Options{
-//			ConnectTimeout: 3e9,
-//			RequestTimeout: 10e9,
-//		},
-//	}
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	var (
-//		user *User
-//		err  error
-//	)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetBigPkg", []interface{}{nil}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.NotEqual(t, "", user.Id)
-//	assert.NotEqual(t, "", user.Name)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "1", Name: "username"}, *user)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser0", []interface{}{"1", nil, "username"}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "1", Name: "username"}, *user)
-//
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser1", []interface{}{}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser2", []interface{}{}, nil), NewResponse(user, nil))
-//	assert.EqualError(t, err, "error")
-//
-//	user2 := []interface{}{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser3", []interface{}{}, nil), NewResponse(&user2, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
-//
-//	user2 = []interface{}{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser4", []interface{}{[]interface{}{"1", "username"}}, nil), NewResponse(&user2, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
-//
-//	user3 := map[interface{}]interface{}{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser5", []interface{}{map[interface{}]interface{}{"id": "1", "name": "username"}}, nil), NewResponse(&user3, nil))
-//	assert.NoError(t, err)
-//	assert.NotNil(t, user3)
-//	assert.Equal(t, &User{Id: "1", Name: "username"}, user3["key"])
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser6", []interface{}{0}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "", Name: ""}, *user)
-//
-//	user = &User{}
-//	err = c.Call(NewRequest("127.0.0.1:20000", url, "GetUser6", []interface{}{1}, nil), NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{Id: "1", Name: ""}, *user)
-//
-//	// destroy
-//	proto.Destroy()
-//}
-//
-//func TestClient_AsyncCall(t *testing.T) {
-//	proto, url := InitTest(t)
-//
-//	c := &Client{
-//		pendingResponses: new(sync.Map),
-//		conf:             *clientConf,
-//		opts: Options{
-//			ConnectTimeout: 3e9,
-//			RequestTimeout: 6e9,
-//		},
-//	}
-//	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
-//
-//	user := &User{}
-//	lock := sync.Mutex{}
-//	lock.Lock()
-//	err := c.AsyncCall(NewRequest("127.0.0.1:20000", url, "GetUser", []interface{}{"1", "username"}, nil), func(response common.CallbackResponse) {
-//		r := response.(AsyncCallbackResponse)
-//		assert.Equal(t, User{Id: "1", Name: "username"}, *r.Reply.(*Response).reply.(*User))
-//		lock.Unlock()
-//	}, NewResponse(user, nil))
-//	assert.NoError(t, err)
-//	assert.Equal(t, User{}, *user)
-//
-//	// destroy
-//	lock.Lock()
-//	proto.Destroy()
-//	lock.Unlock()
-//}
-//
-//func InitTest(t *testing.T) (protocol.Protocol, common.URL) {
-//
-//	hessian.RegisterPOJO(&User{})
-//
-//	methods, err := common.ServiceMap.Register("dubbo", &UserProvider{})
-//	assert.NoError(t, err)
-//	assert.Equal(t, "GetBigPkg,GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4,GetUser5,GetUser6", methods)
-//
-//	// config
-//	SetClientConf(ClientConfig{
-//		ConnectionNum:   2,
-//		HeartbeatPeriod: "5s",
-//		SessionTimeout:  "20s",
-//		PoolTTL:         600,
-//		PoolSize:        64,
-//		GettySessionParam: GettySessionParam{
-//			CompressEncoding: false,
-//			TcpNoDelay:       true,
-//			TcpKeepAlive:     true,
-//			KeepAlivePeriod:  "120s",
-//			TcpRBufSize:      262144,
-//			TcpWBufSize:      65536,
-//			PkgWQSize:        512,
-//			TcpReadTimeout:   "4s",
-//			TcpWriteTimeout:  "5s",
-//			WaitTimeout:      "1s",
-//			MaxMsgLen:        10240000000,
-//			SessionName:      "client",
-//		},
-//	})
-//	assert.NoError(t, clientConf.CheckValidity())
-//	SetServerConfig(ServerConfig{
-//		SessionNumber:  700,
-//		SessionTimeout: "20s",
-//		GettySessionParam: GettySessionParam{
-//			CompressEncoding: false,
-//			TcpNoDelay:       true,
-//			TcpKeepAlive:     true,
-//			KeepAlivePeriod:  "120s",
-//			TcpRBufSize:      262144,
-//			TcpWBufSize:      65536,
-//			PkgWQSize:        512,
-//			TcpReadTimeout:   "1s",
-//			TcpWriteTimeout:  "5s",
-//			WaitTimeout:      "1s",
-//			MaxMsgLen:        10240000000,
-//			SessionName:      "server",
-//		}})
-//	assert.NoError(t, srvConf.CheckValidity())
-//
-//	// Export
-//	proto := GetProtocol()
-//	url, err := common.NewURL("dubbo://127.0.0.1:20000/UserProvider?anyhost=true&" +
-//		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
-//		"environment=dev&interface=com.ikurento.user.UserProvider&ip=192.168.56.1&methods=GetUser%2C&" +
-//		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
-//		"side=provider&timeout=3000&timestamp=1556509797245&bean.name=UserProvider")
-//	assert.NoError(t, err)
-//	proto.Export(&proxy_factory.ProxyInvoker{
-//		BaseInvoker: *protocol.NewBaseInvoker(url),
-//	})
-//
-//	time.Sleep(time.Second * 2)
-//
-//	return proto, url
-//}
-//
-////////////////////////////////////
-//// provider
-////////////////////////////////////
-//
-//type (
-//	User struct {
-//		Id   string `json:"id"`
-//		Name string `json:"name"`
-//	}
-//
-//	UserProvider struct {
-//		user map[string]User
-//	}
-//)
-//
-//// size:4801228
-//func (u *UserProvider) GetBigPkg(ctx context.Context, req []interface{}, rsp *User) error {
-//	argBuf := new(bytes.Buffer)
-//	for i := 0; i < 4000; i++ {
-//		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
-//		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
-//	}
-//	rsp.Id = argBuf.String()
-//	rsp.Name = argBuf.String()
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
-//	rsp.Id = req[0].(string)
-//	rsp.Name = req[1].(string)
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser0(id string, k *User, name string) (User, error) {
-//	return User{Id: id, Name: name}, nil
-//}
-//
-//func (u *UserProvider) GetUser1() error {
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser2() error {
-//	return perrors.New("error")
-//}
-//
-//func (u *UserProvider) GetUser3(rsp *[]interface{}) error {
-//	*rsp = append(*rsp, User{Id: "1", Name: "username"})
-//	return nil
-//}
-//
-//func (u *UserProvider) GetUser4(ctx context.Context, req []interface{}) ([]interface{}, error) {
-//
-//	return []interface{}{User{Id: req[0].([]interface{})[0].(string), Name: req[0].([]interface{})[1].(string)}}, nil
-//}
-//
-//func (u *UserProvider) GetUser5(ctx context.Context, req []interface{}) (map[interface{}]interface{}, error) {
-//	return map[interface{}]interface{}{"key": User{Id: req[0].(map[interface{}]interface{})["id"].(string), Name: req[0].(map[interface{}]interface{})["name"].(string)}}, nil
-//}
-//
-//func (u *UserProvider) GetUser6(id int64) (*User, error) {
-//	if id == 0 {
-//		return nil, nil
-//	}
-//	return &User{Id: "1"}, nil
-//}
-//
-//func (u *UserProvider) Reference() string {
-//	return "UserProvider"
-//}
-//
-//func (u User) JavaClassName() string {
-//	return "com.ikurento.user.User"
-//}
diff --git a/remoting/getty/dubbo_codec_for_test.go b/remoting/getty/dubbo_codec_for_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..46ef7b939e2d2e66ff4bcfecd5c2800520cfa07e
--- /dev/null
+++ b/remoting/getty/dubbo_codec_for_test.go
@@ -0,0 +1,359 @@
+package getty
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"strconv"
+	"time"
+
+	hessian "github.com/apache/dubbo-go-hessian2"
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/common/logger"
+	"github.com/apache/dubbo-go/protocol"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/apache/dubbo-go/remoting"
+	perrors "github.com/pkg/errors"
+)
+
+//SerialID serial ID
+type SerialID byte
+
+const (
+	// S_Dubbo dubbo serial id
+	S_Dubbo SerialID = 2
+)
+
+func init() {
+	codec := &DubboTestCodec{}
+	remoting.NewCodec("dubbo", codec)
+}
+
+// DubboPackage ...
+type DubboPackage struct {
+	Header  hessian.DubboHeader
+	Service hessian.Service
+	Body    interface{}
+	Err     error
+}
+
+func (p DubboPackage) String() string {
+	return fmt.Sprintf("DubboPackage: Header-%v, Path-%v, Body-%v", p.Header, p.Service, p.Body)
+}
+
+// Marshal ...
+func (p *DubboPackage) Marshal() (*bytes.Buffer, error) {
+	codec := hessian.NewHessianCodec(nil)
+
+	pkg, err := codec.Write(p.Service, p.Header, p.Body)
+	if err != nil {
+		return nil, perrors.WithStack(err)
+	}
+
+	return bytes.NewBuffer(pkg), nil
+}
+
+// Unmarshal ...
+func (p *DubboPackage) Unmarshal(buf *bytes.Buffer, resp *remoting.Response) error {
+	// fix issue https://github.com/apache/dubbo-go/issues/380
+	bufLen := buf.Len()
+	if bufLen < hessian.HEADER_LENGTH {
+		return perrors.WithStack(hessian.ErrHeaderNotEnough)
+	}
+
+	codec := hessian.NewHessianCodec(bufio.NewReaderSize(buf, bufLen))
+
+	// read header
+	err := codec.ReadHeader(&p.Header)
+	if err != nil {
+		return perrors.WithStack(err)
+	}
+
+	if resp != nil { // for client
+		if p.Header.Type&hessian.PackageRequest != 0x00 {
+			// size of this array must be '7'
+			// https://github.com/apache/dubbo-go-hessian2/blob/master/request.go#L272
+			p.Body = make([]interface{}, 7)
+		} else {
+			pendingRsp := remoting.GetPendingResponse(remoting.SequenceType(p.Header.ID))
+			if pendingRsp == nil {
+				return perrors.Errorf("client.GetPendingResponse(%v) = nil", p.Header.ID)
+			}
+			p.Body = &hessian.Response{RspObj: pendingRsp.Reply}
+		}
+	}
+
+	// read body
+	err = codec.ReadBody(p.Body)
+	return perrors.WithStack(err)
+}
+
+type DubboTestCodec struct {
+}
+
+func (c *DubboTestCodec) EncodeRequest(request *remoting.Request) (*bytes.Buffer, error) {
+	if request.Event {
+		return c.encodeHeartbeartReqeust(request)
+	}
+
+	invoc, ok := request.Data.(*invocation.RPCInvocation)
+	if !ok {
+		logger.Errorf("encode request failed for parameter type :%+v", request)
+		return nil, perrors.Errorf("encode request failed for parameter type :%+v", request)
+	}
+	invocation := *invoc
+
+	p := &DubboPackage{}
+	p.Service.Path = invocation.AttachmentsByKey(constant.PATH_KEY, "")
+	p.Service.Interface = invocation.AttachmentsByKey(constant.INTERFACE_KEY, "")
+	p.Service.Version = invocation.AttachmentsByKey(constant.VERSION_KEY, "")
+	p.Service.Group = invocation.AttachmentsByKey(constant.GROUP_KEY, "")
+	p.Service.Method = invocation.MethodName()
+
+	timeout, err := strconv.Atoi(invocation.AttachmentsByKey(constant.TIMEOUT_KEY, "3000"))
+	if err != nil {
+		panic(err)
+	}
+	p.Service.Timeout = time.Duration(timeout)
+	//var timeout = request.svcUrl.GetParam(strings.Join([]string{constant.METHOD_KEYS, request.method + constant.RETRIES_KEY}, "."), "")
+	//if len(timeout) != 0 {
+	//	if t, err := time.ParseDuration(timeout); err == nil {
+	//		p.Service.Timeout = t
+	//	}
+	//}
+
+	p.Header.SerialID = byte(S_Dubbo)
+	p.Header.ID = request.Id
+	if request.TwoWay {
+		p.Header.Type = hessian.PackageRequest_TwoWay
+	} else {
+		p.Header.Type = hessian.PackageRequest
+	}
+
+	p.Body = hessian.NewRequest(invocation.Arguments(), invocation.Attachments())
+
+	codec := hessian.NewHessianCodec(nil)
+
+	pkg, err := codec.Write(p.Service, p.Header, p.Body)
+	if err != nil {
+		return nil, perrors.WithStack(err)
+	}
+
+	return bytes.NewBuffer(pkg), nil
+}
+func (c *DubboTestCodec) encodeHeartbeartReqeust(request *remoting.Request) (*bytes.Buffer, error) {
+	pkg := &DubboPackage{}
+	pkg.Body = []interface{}{}
+	pkg.Header.ID = request.Id
+	pkg.Header.Type = hessian.PackageHeartbeat
+	pkg.Header.SerialID = byte(S_Dubbo)
+
+	codec := hessian.NewHessianCodec(nil)
+
+	byt, err := codec.Write(pkg.Service, pkg.Header, pkg.Body)
+	if err != nil {
+		return nil, perrors.WithStack(err)
+	}
+
+	return bytes.NewBuffer(byt), nil
+}
+func (c *DubboTestCodec) EncodeResponse(response *remoting.Response) (*bytes.Buffer, error) {
+	var ptype = hessian.PackageResponse
+	if response.IsHeartbeat() {
+		ptype = hessian.PackageHeartbeat
+	}
+	resp := &DubboPackage{
+		Header: hessian.DubboHeader{
+			SerialID:       response.SerialID,
+			Type:           ptype,
+			ID:             response.Id,
+			ResponseStatus: response.Status,
+		},
+	}
+	if !response.IsHeartbeat() {
+		resp.Body = &hessian.Response{
+			RspObj:      response.Result.(protocol.RPCResult).Rest,
+			Exception:   response.Result.(protocol.RPCResult).Err,
+			Attachments: response.Result.(protocol.RPCResult).Attrs,
+		}
+	}
+
+	//if response.Header.Type&hessian.PackageRequest != 0x00 {
+	//	resp.Body = req.Body
+	//} else {
+	//	resp.Body = nil
+	//}
+	codec := hessian.NewHessianCodec(nil)
+
+	pkg, err := codec.Write(resp.Service, resp.Header, resp.Body)
+	if err != nil {
+		return nil, perrors.WithStack(err)
+	}
+
+	return bytes.NewBuffer(pkg), nil
+}
+func (c *DubboTestCodec) Decode(data []byte) (remoting.DecodeResult, int, error) {
+	if c.isRequest(data) {
+		req, len, err := c.decodeRequest(data)
+		if err != nil {
+			return remoting.DecodeResult{}, len, err
+		}
+		return remoting.DecodeResult{IsRequest: true, Result: req}, len, err
+	} else {
+		resp, len, err := c.decodeResponse(data)
+		if err != nil {
+			return remoting.DecodeResult{}, len, err
+		}
+		return remoting.DecodeResult{IsRequest: false, Result: resp}, len, err
+	}
+}
+func (c *DubboTestCodec) isRequest(data []byte) bool {
+	if data[2]&byte(0x80) == 0x00 {
+		return false
+	}
+	return true
+}
+
+func (c *DubboTestCodec) decodeRequest(data []byte) (*remoting.Request, int, error) {
+	pkg := &DubboPackage{
+		Body: make([]interface{}, 7),
+	}
+	var request *remoting.Request = nil
+	buf := bytes.NewBuffer(data)
+	err := pkg.Unmarshal(buf, nil)
+	if err != nil {
+		originErr := perrors.Cause(err)
+		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
+			//FIXME
+			return nil, 0, originErr
+		}
+		logger.Errorf("pkg.Unmarshal(len(@data):%d) = error:%+v", buf.Len(), err)
+
+		return request, 0, perrors.WithStack(err)
+	}
+	request = &remoting.Request{
+		Id:       pkg.Header.ID,
+		SerialID: pkg.Header.SerialID,
+		TwoWay:   pkg.Header.Type&hessian.PackageRequest_TwoWay != 0x00,
+		Event:    pkg.Header.Type&hessian.PackageHeartbeat != 0x00,
+	}
+	if pkg.Header.Type&hessian.PackageHeartbeat == 0x00 {
+		// convert params of request
+		req := pkg.Body.([]interface{}) // length of body should be 7
+		if len(req) > 0 {
+			//invocation := request.Data.(*invocation.RPCInvocation)
+			var methodName string
+			var args []interface{}
+			var attachments map[string]string = make(map[string]string)
+			if req[0] != nil {
+				//dubbo version
+				request.Version = req[0].(string)
+			}
+			if req[1] != nil {
+				//path
+				attachments[constant.PATH_KEY] = req[1].(string)
+			}
+			if req[2] != nil {
+				//version
+				attachments[constant.VERSION_KEY] = req[2].(string)
+			}
+			if req[3] != nil {
+				//method
+				methodName = req[3].(string)
+			}
+			if req[4] != nil {
+				//argsType
+				//invocation.ParameterTypes(constant., req[1].(string))
+				//argsTypes = req[4].(string)
+			}
+			if req[5] != nil {
+				args = req[5].([]interface{})
+			}
+			if req[6] != nil {
+				attachments = req[6].(map[string]string)
+			}
+			//if pkg.Service.Path == "" && len(attachments[constant.PATH_KEY]) > 0 {
+			//	pkg.Service.Path = attachments[constant.PATH_KEY]
+			//}
+			//if _, ok := attachments[constant.INTERFACE_KEY]; ok {
+			//	pkg.Service.Interface = attachments[constant.INTERFACE_KEY]
+			//} else {
+			//	pkg.Service.Interface = pkg.Service.Path
+			//}
+			//if len(attachments[constant.GROUP_KEY]) > 0 {
+			//	pkg.Service.Group = attachments[constant.GROUP_KEY]
+			//}
+			invoc := invocation.NewRPCInvocationWithOptions(invocation.WithAttachments(attachments),
+				invocation.WithArguments(args), invocation.WithMethodName(methodName))
+			request.Data = invoc
+			//pkg.Body = map[string]interface{}{
+			//	"dubboVersion": dubboVersion,
+			//	"argsTypes":    argsTypes,
+			//	"args":         args,
+			//	"service":      common.ServiceMap.GetService("dubbo", pkg.Service.Path), // path as a key
+			//	"attachments":  attachments,
+			//}
+		}
+	}
+	return request, hessian.HEADER_LENGTH + pkg.Header.BodyLen, nil
+}
+
+func (c *DubboTestCodec) decodeResponse(data []byte) (*remoting.Response, int, error) {
+	pkg := &DubboPackage{}
+	buf := bytes.NewBuffer(data)
+	response := &remoting.Response{}
+	err := pkg.Unmarshal(buf, response)
+	if err != nil {
+		originErr := perrors.Cause(err)
+		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
+			return nil, 0, originErr
+		}
+		logger.Errorf("pkg.Unmarshal(len(@data):%d) = error:%+v", buf.Len(), err)
+
+		return response, 0, perrors.WithStack(err)
+	}
+	response = &remoting.Response{
+		Id: pkg.Header.ID,
+		//Version:  pkg.Header.,
+		SerialID: pkg.Header.SerialID,
+		Status:   pkg.Header.ResponseStatus,
+		Event:    (pkg.Header.Type & hessian.PackageHeartbeat) != 0,
+	}
+	var error error
+	if pkg.Header.Type&hessian.PackageHeartbeat != 0x00 {
+		if pkg.Header.Type&hessian.PackageResponse != 0x00 {
+			logger.Debugf("get rpc heartbeat response{header: %#v, body: %#v}", pkg.Header, pkg.Body)
+			if pkg.Err != nil {
+				logger.Errorf("rpc heartbeat response{error: %#v}", pkg.Err)
+				error = pkg.Err
+			}
+		} else {
+			logger.Debugf("get rpc heartbeat request{header: %#v, service: %#v, body: %#v}", pkg.Header, pkg.Service, pkg.Body)
+			response.Status = hessian.Response_OK
+			//reply(session, p, hessian.PackageHeartbeat)
+		}
+		return response, hessian.HEADER_LENGTH + pkg.Header.BodyLen, error
+	}
+	logger.Debugf("get rpc response{header: %#v, body: %#v}", pkg.Header, pkg.Body)
+	rpcResult := &protocol.RPCResult{}
+	response.Result = rpcResult
+	if pkg.Header.Type&hessian.PackageRequest == 0x00 {
+		if pkg.Err != nil {
+			rpcResult.Err = pkg.Err
+		} else if pkg.Body.(*hessian.Response).Exception != nil {
+			rpcResult.Err = pkg.Body.(*hessian.Response).Exception
+			response.Error = rpcResult.Err
+		}
+		rpcResult.Attrs = pkg.Body.(*hessian.Response).Attachments
+		rpcResult.Rest = pkg.Body.(*hessian.Response).RspObj
+	}
+
+	//h.conn.updateSession(session)
+	//pendingResponse := h.conn.pool.rpcClient.removePendingResponse(SequenceType(p.Header.ID))
+	//if pendingResponse == nil {
+	//	logger.Errorf("failed to get pending response context for response package %s", *p)
+	//	return
+	//}
+
+	return response, hessian.HEADER_LENGTH + pkg.Header.BodyLen, nil
+}
diff --git a/remoting/getty/getty_client.go b/remoting/getty/getty_client.go
index c22f576872387448c187ecaa39d8603865b854ce..8544b8e17f4b93cd3a0bd1d47c5e8b96b7002e2e 100644
--- a/remoting/getty/getty_client.go
+++ b/remoting/getty/getty_client.go
@@ -18,22 +18,19 @@
 package getty
 
 import (
-	"github.com/apache/dubbo-go/remoting"
-	"gopkg.in/yaml.v2"
 	"math/rand"
 	"time"
-)
 
-import (
+	"github.com/apache/dubbo-go/remoting"
 	"github.com/dubbogo/getty"
+	"gopkg.in/yaml.v2"
+
 	gxsync "github.com/dubbogo/gost/sync"
-	perrors "github.com/pkg/errors"
-)
 
-import (
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/logger"
 	"github.com/apache/dubbo-go/config"
+	perrors "github.com/pkg/errors"
 )
 
 var (
@@ -98,11 +95,6 @@ func SetClientConf(c ClientConfig) {
 	setClientGrpool()
 }
 
-// GetClientConf ...
-func GetClientConf() ClientConfig {
-	return *clientConf
-}
-
 func setClientGrpool() {
 	if clientConf.GrPoolSize > 1 {
 		clientGrpool = gxsync.NewTaskPool(gxsync.WithTaskPoolTaskPoolSize(clientConf.GrPoolSize), gxsync.WithTaskPoolTaskQueueLength(clientConf.QueueLen),
@@ -114,19 +106,17 @@ func setClientGrpool() {
 type Options struct {
 	// connect timeout
 	ConnectTimeout time.Duration
-	// request timeout
-	//RequestTimeout time.Duration
 }
 
-//AsyncCallbackResponse async response for dubbo
-type AsyncCallbackResponse struct {
-	common.CallbackResponse
-	Opts      Options
-	Cause     error
-	Start     time.Time // invoke(call) start time == write start time
-	ReadStart time.Time // read start time, write duration = ReadStart - Start
-	Reply     interface{}
-}
+////AsyncCallbackResponse async response for dubbo
+//type AsyncCallbackResponse struct {
+//	common.CallbackResponse
+//	Opts      Options
+//	Cause     error
+//	Start     time.Time // invoke(call) start time == write start time
+//	ReadStart time.Time // read start time, write duration = ReadStart - Start
+//	Reply     interface{}
+//}
 
 // Client ...
 type Client struct {
@@ -137,8 +127,6 @@ type Client struct {
 	codec           remoting.Codec
 	responseHandler remoting.ResponseHandler
 	ExchangeClient  *remoting.ExchangeClient
-	//sequence atomic.Uint64
-	//pendingResponses *sync.Map
 }
 
 // NewClient ...
@@ -160,6 +148,7 @@ func (c *Client) SetExchangeClient(client *remoting.ExchangeClient) {
 func (c *Client) SetResponseHandler(responseHandler remoting.ResponseHandler) {
 	c.responseHandler = responseHandler
 }
+
 func (c *Client) Connect(url common.URL) {
 	initClient(url.Protocol)
 	c.conf = *clientConf
@@ -169,41 +158,15 @@ func (c *Client) Connect(url common.URL) {
 	c.codec = remoting.GetCodec(url.Protocol)
 	c.addr = url.Location
 }
+
 func (c *Client) Close() {
 	if c.pool != nil {
 		c.pool.close()
 	}
 	c.pool = nil
 }
-func (c *Client) Request(request *remoting.Request, timeout time.Duration, callback common.AsyncCallback, response *remoting.PendingResponse) error {
 
-	//p := &DubboPackage{}
-	//p.Service.Path = strings.TrimPrefix(request.svcUrl.Path, "/")
-	//p.Service.Interface = request.svcUrl.GetParam(constant.INTERFACE_KEY, "")
-	//p.Service.Version = request.svcUrl.GetParam(constant.VERSION_KEY, "")
-	//p.Service.Group = request.svcUrl.GetParam(constant.GROUP_KEY, "")
-	//p.Service.Method = request.method
-	//
-	//p.Service.Timeout = c.opts.RequestTimeout
-	//var timeout = request.svcUrl.GetParam(strings.Join([]string{constant.METHOD_KEYS, request.method + constant.RETRIES_KEY}, "."), "")
-	//if len(timeout) != 0 {
-	//	if t, err := time.ParseDuration(timeout); err == nil {
-	//		p.Service.Timeout = t
-	//	}
-	//}
-	//
-	//p.Header.SerialID = byte(S_Dubbo)
-	//p.Body = hessian.NewRequest(request.args, request.atta)
-	//
-	//var rsp *PendingResponse
-	//if ct != CT_OneWay {
-	//	p.Header.Type = hessian.PackageRequest_TwoWay
-	//	rsp = NewPendingResponse()
-	//	rsp.response = response
-	//	rsp.callback = callback
-	//} else {
-	//	p.Header.Type = hessian.PackageRequest
-	//}
+func (c *Client) Request(request *remoting.Request, timeout time.Duration, response *remoting.PendingResponse) error {
 
 	var (
 		err     error
@@ -225,11 +188,11 @@ func (c *Client) Request(request *remoting.Request, timeout time.Duration, callb
 		conn.close()
 	}()
 
-	if err = c.transfer(session, request, timeout, response); err != nil {
+	if err = c.transfer(session, request, timeout); err != nil {
 		return perrors.WithStack(err)
 	}
 
-	if !request.TwoWay || callback != nil {
+	if !request.TwoWay || response.Callback != nil {
 		return nil
 	}
 
@@ -243,98 +206,6 @@ func (c *Client) Request(request *remoting.Request, timeout time.Duration, callb
 	return perrors.WithStack(err)
 }
 
-// CallOneway call one way
-//func (c *Client) CallOneway(request *Request) error {
-//
-//	return perrors.WithStack(c.call(CT_OneWay, request, NewResponse(nil, nil), nil))
-//}
-//
-//// Call if @response is nil, the transport layer will get the response without notify the invoker.
-//func (c *Client) Call(request *Request, response *Response) error {
-//
-//	ct := CT_TwoWay
-//	if response.reply == nil {
-//		ct = CT_OneWay
-//	}
-//
-//	return perrors.WithStack(c.call(ct, request, response, nil))
-//}
-//
-//// AsyncCall ...
-//func (c *Client) AsyncCall(request *Request, callback common.AsyncCallback, response *Response) error {
-//
-//	return perrors.WithStack(c.call(CT_TwoWay, request, response, callback))
-//}
-//
-//func (c *Client) call(ct CallType, request *Request, response *Response, callback common.AsyncCallback) error {
-//
-//	p := &DubboPackage{}
-//	p.Service.Path = strings.TrimPrefix(request.svcUrl.Path, "/")
-//	p.Service.Interface = request.svcUrl.GetParam(constant.INTERFACE_KEY, "")
-//	p.Service.Version = request.svcUrl.GetParam(constant.VERSION_KEY, "")
-//	p.Service.Group = request.svcUrl.GetParam(constant.GROUP_KEY, "")
-//	p.Service.Method = request.method
-//
-//	p.Service.Timeout = c.opts.RequestTimeout
-//	var timeout = request.svcUrl.GetParam(strings.Join([]string{constant.METHOD_KEYS, request.method + constant.RETRIES_KEY}, "."), "")
-//	if len(timeout) != 0 {
-//		if t, err := time.ParseDuration(timeout); err == nil {
-//			p.Service.Timeout = t
-//		}
-//	}
-//
-//	p.Header.SerialID = byte(S_Dubbo)
-//	p.Body = hessian.NewRequest(request.args, request.atta)
-//
-//	var rsp *PendingResponse
-//	if ct != CT_OneWay {
-//		p.Header.Type = hessian.PackageRequest_TwoWay
-//		rsp = NewPendingResponse()
-//		rsp.response = response
-//		rsp.callback = callback
-//	} else {
-//		p.Header.Type = hessian.PackageRequest
-//	}
-//
-//	var (
-//		err     error
-//		session getty.Session
-//		conn    *gettyRPCClient
-//	)
-//	conn, session, err = c.selectSession(request.addr)
-//	if err != nil {
-//		return perrors.WithStack(err)
-//	}
-//	if session == nil {
-//		return errSessionNotExist
-//	}
-//	defer func() {
-//		if err == nil {
-//			c.pool.put(conn)
-//			return
-//		}
-//		conn.close()
-//	}()
-//
-//	if err = c.transfer(session, p, rsp); err != nil {
-//		return perrors.WithStack(err)
-//	}
-//
-//	if ct == CT_OneWay || callback != nil {
-//		return nil
-//	}
-//
-//	select {
-//	case <-getty.GetTimeWheel().After(c.opts.RequestTimeout):
-//		c.removePendingResponse(SequenceType(rsp.seq))
-//		return perrors.WithStack(errClientReadTimeout)
-//	case <-rsp.done:
-//		err = rsp.err
-//	}
-//
-//	return perrors.WithStack(err)
-//}
-
 func (c *Client) selectSession(addr string) (*gettyRPCClient, getty.Session, error) {
 	rpcClient, err := c.pool.getGettyRpcClient(addr)
 	if err != nil {
@@ -349,49 +220,15 @@ func (c *Client) heartbeat(session getty.Session) error {
 	req.Event = true
 	resp := remoting.NewPendingResponse(req.Id)
 	remoting.AddPendingResponse(resp)
-	return c.transfer(session, req, 3*time.Second, resp)
+	return c.transfer(session, req, 3*time.Second)
 }
 
-func (c *Client) transfer(session getty.Session, request *remoting.Request, timeout time.Duration,
-	rsp *remoting.PendingResponse) error {
-	//sequence = c.sequence.Add(1)
-	//
-	//if pkg == nil {
-	//	pkg = &DubboPackage{}
-	//	pkg.Body = hessian.NewRequest([]interface{}{}, nil)
-	//	pkg.Body = []interface{}{}
-	//	pkg.Header.Type = hessian.PackageHeartbeat
-	//	pkg.Header.SerialID = byte(S_Dubbo)
-	//}
-	//pkg.Header.ID = int64(sequence)
-
-	// cond1
-	//if rsp != nil {
-	//	c.addPendingResponse(rsp)
-	//}
-
+func (c *Client) transfer(session getty.Session, request *remoting.Request, timeout time.Duration) error {
 	err := session.WritePkg(request, timeout)
-	if rsp != nil { // cond2
-		// cond2 should not merged with cond1. cause the response package may be returned very
-		// soon and it will be handled by other goroutine.
-		rsp.ReadStart = time.Now()
-	}
-
+	//if rsp != nil { // cond2
+	//	// cond2 should not merged with cond1. cause the response package may be returned very
+	//	// soon and it will be handled by other goroutine.
+	//	rsp.ReadStart = time.Now()
+	//}
 	return perrors.WithStack(err)
 }
-
-//
-//func (c *Client) addPendingResponse(pr *PendingResponse) {
-//	c.pendingResponses.Store(SequenceType(pr.seq), pr)
-//}
-//
-//func (c *Client) removePendingResponse(seq SequenceType) *PendingResponse {
-//	if c.pendingResponses == nil {
-//		return nil
-//	}
-//	if presp, ok := c.pendingResponses.Load(seq); ok {
-//		c.pendingResponses.Delete(seq)
-//		return presp.(*PendingResponse)
-//	}
-//	return nil
-//}
diff --git a/remoting/getty/getty_client_test.go b/remoting/getty/getty_client_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9fa46daaf3fbeee6b5802e8df5e322f93c0fa9dd
--- /dev/null
+++ b/remoting/getty/getty_client_test.go
@@ -0,0 +1,497 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package getty
+
+import (
+	"bytes"
+	"context"
+	"reflect"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/apache/dubbo-go/common/proxy/proxy_factory"
+
+	"github.com/apache/dubbo-go/config"
+
+	"github.com/apache/dubbo-go/remoting"
+
+	"github.com/apache/dubbo-go/protocol/invocation"
+
+	hessian "github.com/apache/dubbo-go-hessian2"
+
+	"github.com/apache/dubbo-go/common"
+	. "github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/protocol"
+	perrors "github.com/pkg/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRunSuite(t *testing.T) {
+	svr, url := InitTest(t)
+	client := getClient(url)
+	testRequestOneWay(t, svr, url, client)
+	testClient_Call(t, svr, url, client)
+	testClient_AsyncCall(t, svr, url, client)
+
+	svr.Stop()
+}
+
+func testRequestOneWay(t *testing.T, svr *Server, url common.URL, client *Client) {
+
+	request := remoting.NewRequest("2.0.2")
+	up := &UserProvider{}
+	invocation := createInvocation("GetUser", nil, nil, []interface{}{[]interface{}{"1", "username"}, up},
+		[]reflect.Value{reflect.ValueOf([]interface{}{"1", "username"}), reflect.ValueOf(up)})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = false
+	//user := &User{}
+	err := client.Request(request, 3*time.Second, nil)
+	assert.NoError(t, err)
+}
+
+func createInvocation(methodName string, callback interface{}, reply interface{}, arguments []interface{},
+	parameterValues []reflect.Value) *invocation.RPCInvocation {
+	return invocation.NewRPCInvocationWithOptions(invocation.WithMethodName(methodName),
+		invocation.WithArguments(arguments), invocation.WithReply(reply),
+		invocation.WithCallBack(callback), invocation.WithParameterValues(parameterValues))
+}
+
+func setAttachment(invocation *invocation.RPCInvocation, attachments map[string]string) {
+	for key, value := range attachments {
+		invocation.SetAttachments(key, value)
+	}
+}
+
+func getClient(url common.URL) *Client {
+	client := NewClient(Options{
+		ConnectTimeout: config.GetConsumerConfig().ConnectTimeout,
+	})
+
+	exchangeClient := remoting.NewExchangeClient(url, client, 5*time.Second)
+	client.SetExchangeClient(exchangeClient)
+	client.Connect(url)
+	client.SetResponseHandler(exchangeClient)
+	return client
+}
+
+func testClient_Call(t *testing.T, svr *Server, url common.URL, c *Client) {
+	c.pool = newGettyRPCClientConnPool(c, clientConf.PoolSize, time.Duration(int(time.Second)*clientConf.PoolTTL))
+
+	testGetBigPkg(t, c)
+	testGetUser(t, c)
+	testGetUser0(t, c)
+	testGetUser1(t, c)
+	testGetUser2(t, c)
+	testGetUser3(t, c)
+	testGetUser4(t, c)
+	testGetUser5(t, c)
+	testGetUser6(t, c)
+	testGetUser61(t, c)
+
+}
+func testGetBigPkg(t *testing.T, c *Client) {
+	var (
+		user *User
+		err  error
+	)
+
+	user = &User{}
+	request := remoting.NewRequest("2.0.2")
+	invocation := createInvocation("GetBigPkg", nil, nil, []interface{}{[]interface{}{nil}, user},
+		[]reflect.Value{reflect.ValueOf([]interface{}{nil}), reflect.ValueOf(user)})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	pendingResponse.Reply = user
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 8*time.Second, pendingResponse)
+	assert.NoError(t, err)
+	assert.NotEqual(t, "", user.Id)
+	assert.NotEqual(t, "", user.Name)
+}
+func testGetUser(t *testing.T, c *Client) {
+	var (
+		user *User
+		err  error
+	)
+	user = &User{}
+	request := remoting.NewRequest("2.0.2")
+	invocation := createInvocation("GetUser", nil, nil, []interface{}{"1", "username"},
+		[]reflect.Value{reflect.ValueOf("1"), reflect.ValueOf("username")})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	pendingResponse.Reply = user
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.NoError(t, err)
+	assert.Equal(t, User{Id: "1", Name: "username"}, *user)
+}
+
+func testGetUser0(t *testing.T, c *Client) {
+	var (
+		user *User
+		err  error
+	)
+	user = &User{}
+	request := remoting.NewRequest("2.0.2")
+	invocation := createInvocation("GetUser0", nil, nil, []interface{}{"1", nil, "username"},
+		[]reflect.Value{reflect.ValueOf("1"), reflect.ValueOf(nil), reflect.ValueOf("username")})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	rsp := remoting.NewPendingResponse(request.Id)
+	rsp.SetResponse(remoting.NewResponse(request.Id, "2.0.2"))
+	remoting.AddPendingResponse(rsp)
+	rsp.Reply = user
+	err = c.Request(request, 3*time.Second, rsp)
+	assert.NoError(t, err)
+	assert.Equal(t, User{Id: "1", Name: "username"}, *user)
+}
+func testGetUser1(t *testing.T, c *Client) {
+	var (
+		err error
+	)
+	request := remoting.NewRequest("2.0.2")
+	invocation := createInvocation("GetUser1", nil, nil, []interface{}{},
+		[]reflect.Value{})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	user := &User{}
+	pendingResponse.Reply = user
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.NoError(t, err)
+}
+func testGetUser2(t *testing.T, c *Client) {
+	var (
+		err error
+	)
+	request := remoting.NewRequest("2.0.2")
+	invocation := createInvocation("GetUser2", nil, nil, []interface{}{},
+		[]reflect.Value{})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.EqualError(t, err, "error")
+}
+func testGetUser3(t *testing.T, c *Client) {
+	var (
+		err error
+	)
+	request := remoting.NewRequest("2.0.2")
+	invocation := createInvocation("GetUser3", nil, nil, []interface{}{},
+		[]reflect.Value{})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	user2 := []interface{}{}
+	pendingResponse.Reply = &user2
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.NoError(t, err)
+	assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
+}
+func testGetUser4(t *testing.T, c *Client) {
+	var (
+		err error
+	)
+	request := remoting.NewRequest("2.0.2")
+	invocation := invocation.NewRPCInvocation("GetUser4", []interface{}{[]interface{}{"1", "username"}}, nil)
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	user2 := []interface{}{}
+	pendingResponse.Reply = &user2
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.NoError(t, err)
+	assert.Equal(t, &User{Id: "1", Name: "username"}, user2[0])
+}
+
+func testGetUser5(t *testing.T, c *Client) {
+	var (
+		err error
+	)
+	request := remoting.NewRequest("2.0.2")
+	invocation := invocation.NewRPCInvocation("GetUser5", []interface{}{map[interface{}]interface{}{"id": "1", "name": "username"}}, nil)
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	user3 := map[interface{}]interface{}{}
+	pendingResponse.Reply = &user3
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.NoError(t, err)
+	assert.NotNil(t, user3)
+	assert.Equal(t, &User{Id: "1", Name: "username"}, user3["key"])
+}
+
+func testGetUser6(t *testing.T, c *Client) {
+	var (
+		user *User
+		err  error
+	)
+	user = &User{}
+	request := remoting.NewRequest("2.0.2")
+	invocation := invocation.NewRPCInvocation("GetUser6", []interface{}{0}, nil)
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	pendingResponse.Reply = user
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.NoError(t, err)
+	assert.Equal(t, User{Id: "", Name: ""}, *user)
+}
+
+func testGetUser61(t *testing.T, c *Client) {
+	var (
+		user *User
+		err  error
+	)
+	user = &User{}
+	request := remoting.NewRequest("2.0.2")
+	invocation := invocation.NewRPCInvocation("GetUser6", []interface{}{1}, nil)
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	pendingResponse := remoting.NewPendingResponse(request.Id)
+	pendingResponse.Reply = user
+	remoting.AddPendingResponse(pendingResponse)
+	err = c.Request(request, 3*time.Second, pendingResponse)
+	assert.NoError(t, err)
+	assert.Equal(t, User{Id: "1", Name: ""}, *user)
+}
+
+func testClient_AsyncCall(t *testing.T, svr *Server, url common.URL, client *Client) {
+	user := &User{}
+	lock := sync.Mutex{}
+	request := remoting.NewRequest("2.0.2")
+	invocation := createInvocation("GetUser0", nil, nil, []interface{}{"4", nil, "username"},
+		[]reflect.Value{reflect.ValueOf("4"), reflect.ValueOf(nil), reflect.ValueOf("username")})
+	attachment := map[string]string{INTERFACE_KEY: "com.ikurento.user.UserProvider"}
+	setAttachment(invocation, attachment)
+	request.Data = invocation
+	request.Event = false
+	request.TwoWay = true
+	rsp := remoting.NewPendingResponse(request.Id)
+	rsp.SetResponse(remoting.NewResponse(request.Id, "2.0.2"))
+	remoting.AddPendingResponse(rsp)
+	rsp.Reply = user
+	rsp.Callback = func(response common.CallbackResponse) {
+		r := response.(remoting.AsyncCallbackResponse)
+		rst := *r.Reply.(*remoting.Response).Result.(*protocol.RPCResult)
+		assert.Equal(t, User{Id: "4", Name: "username"}, *(rst.Rest.(*User)))
+		lock.Unlock()
+	}
+	lock.Lock()
+	err := client.Request(request, 3*time.Second, rsp)
+	assert.NoError(t, err)
+	assert.Equal(t, User{}, *user)
+	time.Sleep(1 * time.Second)
+}
+
+func InitTest(t *testing.T) (*Server, common.URL) {
+
+	hessian.RegisterPOJO(&User{})
+	remoting.NewCodec("dubbo", &DubboTestCodec{})
+
+	methods, err := common.ServiceMap.Register("dubbo", &UserProvider{})
+	assert.NoError(t, err)
+	assert.Equal(t, "GetBigPkg,GetUser,GetUser0,GetUser1,GetUser2,GetUser3,GetUser4,GetUser5,GetUser6", methods)
+
+	// config
+	SetClientConf(ClientConfig{
+		ConnectionNum:   2,
+		HeartbeatPeriod: "5s",
+		SessionTimeout:  "20s",
+		PoolTTL:         600,
+		PoolSize:        64,
+		GettySessionParam: GettySessionParam{
+			CompressEncoding: false,
+			TcpNoDelay:       true,
+			TcpKeepAlive:     true,
+			KeepAlivePeriod:  "120s",
+			TcpRBufSize:      262144,
+			TcpWBufSize:      65536,
+			PkgWQSize:        512,
+			TcpReadTimeout:   "4s",
+			TcpWriteTimeout:  "5s",
+			WaitTimeout:      "1s",
+			MaxMsgLen:        10240000000,
+			SessionName:      "client",
+		},
+	})
+	assert.NoError(t, clientConf.CheckValidity())
+	SetServerConfig(ServerConfig{
+		SessionNumber:  700,
+		SessionTimeout: "20s",
+		GettySessionParam: GettySessionParam{
+			CompressEncoding: false,
+			TcpNoDelay:       true,
+			TcpKeepAlive:     true,
+			KeepAlivePeriod:  "120s",
+			TcpRBufSize:      262144,
+			TcpWBufSize:      65536,
+			PkgWQSize:        512,
+			TcpReadTimeout:   "1s",
+			TcpWriteTimeout:  "5s",
+			WaitTimeout:      "1s",
+			MaxMsgLen:        10240000000,
+			SessionName:      "server",
+		}})
+	assert.NoError(t, srvConf.CheckValidity())
+
+	url, err := common.NewURL("dubbo://127.0.0.1:20060/UserProvider?anyhost=true&" +
+		"application=BDTService&category=providers&default.timeout=10000&dubbo=dubbo-provider-golang-1.0.0&" +
+		"environment=dev&interface=com.ikurento.user.UserProvider&ip=127.0.0.1&methods=GetUser%2C&" +
+		"module=dubbogo+user-info+server&org=ikurento.com&owner=ZX&pid=1447&revision=0.0.1&" +
+		"side=provider&timeout=3000&timestamp=1556509797245&bean.name=UserProvider")
+	// init server
+	userProvider := &UserProvider{}
+	common.ServiceMap.Register(url.Protocol, userProvider)
+	invoker := &proxy_factory.ProxyInvoker{
+		BaseInvoker: *protocol.NewBaseInvoker(url),
+	}
+	handler := func(invocation *invocation.RPCInvocation) protocol.RPCResult {
+		//result := protocol.RPCResult{}
+		r := invoker.Invoke(context.Background(), invocation)
+		result := protocol.RPCResult{
+			Err:   r.Error(),
+			Rest:  r.Result(),
+			Attrs: r.Attachments(),
+		}
+		return result
+	}
+	server := NewServer(url, handler)
+	server.Start()
+
+	time.Sleep(time.Second * 2)
+
+	return server, url
+}
+
+//////////////////////////////////
+// provider
+//////////////////////////////////
+
+type (
+	User struct {
+		Id   string `json:"id"`
+		Name string `json:"name"`
+	}
+
+	UserProvider struct {
+		user map[string]User
+	}
+)
+
+// size:4801228
+func (u *UserProvider) GetBigPkg(ctx context.Context, req []interface{}, rsp *User) error {
+	argBuf := new(bytes.Buffer)
+	for i := 0; i < 400; i++ {
+		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
+		argBuf.WriteString("击鼓其镗,踊跃用兵。土国城漕,我独南行。从孙子仲,平陈与宋。不我以归,忧心有忡。爰居爰处?爰丧其马?于以求之?于林之下。死生契阔,与子成说。执子之手,与子偕老。于嗟阔兮,不我活兮。于嗟洵兮,不我信兮。")
+	}
+	rsp.Id = argBuf.String()
+	rsp.Name = argBuf.String()
+	return nil
+}
+
+func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
+	rsp.Id = req[0].(string)
+	rsp.Name = req[1].(string)
+	return nil
+}
+
+func (u *UserProvider) GetUser0(id string, k *User, name string) (User, error) {
+	return User{Id: id, Name: name}, nil
+}
+
+func (u *UserProvider) GetUser1() error {
+	return nil
+}
+
+func (u *UserProvider) GetUser2() error {
+	return perrors.New("error")
+}
+
+func (u *UserProvider) GetUser3(rsp *[]interface{}) error {
+	*rsp = append(*rsp, User{Id: "1", Name: "username"})
+	return nil
+}
+
+func (u *UserProvider) GetUser4(ctx context.Context, req []interface{}) ([]interface{}, error) {
+
+	return []interface{}{User{Id: req[0].([]interface{})[0].(string), Name: req[0].([]interface{})[1].(string)}}, nil
+}
+
+func (u *UserProvider) GetUser5(ctx context.Context, req []interface{}) (map[interface{}]interface{}, error) {
+	return map[interface{}]interface{}{"key": User{Id: req[0].(map[interface{}]interface{})["id"].(string), Name: req[0].(map[interface{}]interface{})["name"].(string)}}, nil
+}
+
+func (u *UserProvider) GetUser6(id int64) (*User, error) {
+	if id == 0 {
+		return nil, nil
+	}
+	return &User{Id: "1"}, nil
+}
+
+func (u *UserProvider) Reference() string {
+	return "UserProvider"
+}
+
+func (u User) JavaClassName() string {
+	return "com.ikurento.user.User"
+}
diff --git a/remoting/getty/server.go b/remoting/getty/getty_server.go
similarity index 98%
rename from remoting/getty/server.go
rename to remoting/getty/getty_server.go
index 00fba5cae371f846ccd0d19233af6d723ac256e4..874d0401f50e08583a7fec264701ebf684342698 100644
--- a/remoting/getty/server.go
+++ b/remoting/getty/getty_server.go
@@ -19,22 +19,18 @@ package getty
 
 import (
 	"fmt"
+	"net"
+
 	"github.com/apache/dubbo-go/protocol"
 	"github.com/apache/dubbo-go/protocol/invocation"
 	"github.com/apache/dubbo-go/remoting"
-	"net"
-)
-
-import (
 	"github.com/dubbogo/getty"
-	"github.com/dubbogo/gost/sync"
-	"gopkg.in/yaml.v2"
-)
 
-import (
 	"github.com/apache/dubbo-go/common"
 	"github.com/apache/dubbo-go/common/logger"
 	"github.com/apache/dubbo-go/config"
+	gxsync "github.com/dubbogo/gost/sync"
+	"gopkg.in/yaml.v2"
 )
 
 var (
diff --git a/remoting/getty/listener.go b/remoting/getty/listener.go
index 0dc2792a239bc432b91659f35a59a65f571f2f51..156a4046cb1704c95d87bcd6d8034867b68b1a6e 100644
--- a/remoting/getty/listener.go
+++ b/remoting/getty/listener.go
@@ -18,25 +18,20 @@
 package getty
 
 import (
-	"context"
 	"fmt"
-	"github.com/apache/dubbo-go/remoting"
 	"sync"
 	"sync/atomic"
 	"time"
-)
-
-import (
-	"github.com/apache/dubbo-go-hessian2"
-	"github.com/dubbogo/getty"
-	"github.com/opentracing/opentracing-go"
-	perrors "github.com/pkg/errors"
-)
 
-import (
 	"github.com/apache/dubbo-go/common/constant"
+
+	"github.com/apache/dubbo-go/remoting"
+
+	hessian "github.com/apache/dubbo-go-hessian2"
 	"github.com/apache/dubbo-go/common/logger"
 	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/dubbogo/getty"
+	perrors "github.com/pkg/errors"
 )
 
 // todo: WritePkg_Timeout will entry *.yml
@@ -96,37 +91,48 @@ func (h *RpcClientHandler) OnClose(session getty.Session) {
 
 // OnMessage ...
 func (h *RpcClientHandler) OnMessage(session getty.Session, pkg interface{}) {
-	p, ok := pkg.(*remoting.Response)
+	result, ok := pkg.(remoting.DecodeResult)
 	if !ok {
 		logger.Errorf("illegal package")
 		return
 	}
+	// get heartbeart request from server
+	if result.IsRequest {
+		req := result.Result.(*remoting.Request)
+		if req.Event {
+			logger.Debugf("get rpc heartbeat request{%#v}", req)
+			resp := remoting.NewResponse(req.Id, req.Version)
+			resp.Status = hessian.Response_OK
+			resp.Event = req.Event
+			resp.SerialID = req.SerialID
+			resp.Version = "2.0.2"
+			reply(session, resp, hessian.PackageHeartbeat)
+			return
+		}
+		logger.Errorf("illegal request but not heartbeart. {%#v}", req)
+		return
+	}
 
+	p := result.Result.(*remoting.Response)
+	// get heartbeart
 	if p.Event {
 		logger.Debugf("get rpc heartbeat response{%#v}", p)
 		if p.Error != nil {
 			logger.Errorf("rpc heartbeat response{error: %#v}", p.Error)
 		}
-		(h.conn.pool.rpcClient.responseHandler).Handler(p)
-		//FIXME
-		//if p.Header.Type&hessian.PackageResponse != 0x00 {
-		//	logger.Debugf("get rpc heartbeat response{header: %#v, body: %#v}", p.Header, p.Body)
-		//	if p.Err != nil {
-		//		logger.Errorf("rpc heartbeat response{error: %#v}", p.Err)
-		//	}
-		//	h.conn.pool.rpcClient.removePendingResponse(SequenceType(p.Header.ID))
-		//} else {
-		//	logger.Debugf("get rpc heartbeat request{header: %#v, service: %#v, body: %#v}", p.Header, p.Service, p.Body)
-		//	p.Header.ResponseStatus = hessian.Response_OK
-		//	reply(session, p, hessian.PackageHeartbeat)
-		//}
+		h.conn.pool.rpcClient.responseHandler.Handler(p)
+		return
+	}
+	if result.IsRequest {
+		logger.Errorf("illegal package for it is response type. {%#v}", pkg)
 		return
 	}
+
 	logger.Debugf("get rpc response{%#v}", p)
 
 	h.conn.updateSession(session)
 
-	(h.conn.pool.rpcClient.responseHandler).Handler(p)
+	h.conn.pool.rpcClient.responseHandler.Handler(p)
 
 	//
 	//pendingResponse := h.conn.pool.rpcClient.removePendingResponse(SequenceType(p.Header.ID))
@@ -232,11 +238,17 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) {
 	}
 	h.rwlock.Unlock()
 
-	req, ok := pkg.(*remoting.Request)
+	decodeResult, ok := pkg.(remoting.DecodeResult)
 	if !ok {
 		logger.Errorf("illegal package{%#v}", pkg)
 		return
 	}
+	if !decodeResult.IsRequest {
+		logger.Errorf("illegal package for it is response type. {%#v}", pkg)
+		return
+	}
+	req := decodeResult.Result.(*remoting.Request)
+
 	resp := remoting.NewResponse(req.Id, req.Version)
 	resp.Status = hessian.Response_OK
 	resp.Event = req.Event
@@ -280,8 +292,13 @@ func (h *RpcServerHandler) OnMessage(session getty.Session, pkg interface{}) {
 
 	invoc, ok := req.Data.(*invocation.RPCInvocation)
 	if !ok {
-
+		panic("create invocation occur some exception for the type is not suitable one.")
+		return
 	}
+	attachments := invoc.Attachments()
+	attachments[constant.LOCAL_ADDR] = session.LocalAddr()
+	attachments[constant.REMOTE_ADDR] = session.RemoteAddr()
+
 	result := h.server.requestHandler(invoc)
 	if !req.TwoWay {
 		return
@@ -316,21 +333,6 @@ func (h *RpcServerHandler) OnCron(session getty.Session) {
 	}
 }
 
-// rebuildCtx rebuild the context by attachment.
-// Once we decided to transfer more context's key-value, we should change this.
-// now we only support rebuild the tracing context
-func RebuildCtx(inv *invocation.RPCInvocation) context.Context {
-	ctx := context.Background()
-
-	// actually, if user do not use any opentracing framework, the err will not be nil.
-	spanCtx, err := opentracing.GlobalTracer().Extract(opentracing.TextMap,
-		opentracing.TextMapCarrier(inv.Attachments()))
-	if err == nil {
-		ctx = context.WithValue(ctx, constant.TRACING_REMOTE_SPAN_CTX, spanCtx)
-	}
-	return ctx
-}
-
 func reply(session getty.Session, resp *remoting.Response, tp hessian.PackageType) {
 	//resp := &DubboPackage{
 	//	Header: hessian.DubboHeader{
diff --git a/remoting/getty/listener_test.go b/remoting/getty/listener_test.go
index a7feeddce0ee709f99a9cd9fb4616036ddcb3689..49e13d39c9f14ea48551f54f0b1c7f880d1bdd5e 100644
--- a/remoting/getty/listener_test.go
+++ b/remoting/getty/listener_test.go
@@ -17,42 +17,53 @@
 
 package getty
 
-//import (
-//	"testing"
-//)
-//
-//import (
-//	"github.com/opentracing/opentracing-go"
-//	"github.com/opentracing/opentracing-go/mocktracer"
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//import (
-//	"github.com/apache/dubbo-go/common/constant"
-//	"github.com/apache/dubbo-go/protocol/invocation"
-//)
-//
-//// test rebuild the ctx
-//func TestRebuildCtx(t *testing.T) {
-//	opentracing.SetGlobalTracer(mocktracer.New())
-//	attach := make(map[string]string, 10)
-//	attach[constant.VERSION_KEY] = "1.0"
-//	attach[constant.GROUP_KEY] = "MyGroup"
-//	inv := invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
-//
-//	// attachment doesn't contains any tracing key-value pair,
-//	ctx := rebuildCtx(inv)
-//	assert.NotNil(t, ctx)
-//	assert.Nil(t, ctx.Value(constant.TRACING_REMOTE_SPAN_CTX))
-//
-//	span, ctx := opentracing.StartSpanFromContext(ctx, "Test-Client")
-//
-//	opentracing.GlobalTracer().Inject(span.Context(), opentracing.TextMap,
-//		opentracing.TextMapCarrier(inv.Attachments()))
-//	// rebuild the context success
-//	inv = invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
-//	ctx = rebuildCtx(inv)
-//	span.Finish()
-//	assert.NotNil(t, ctx)
-//	assert.NotNil(t, ctx.Value(constant.TRACING_REMOTE_SPAN_CTX))
-//}
+import (
+	"context"
+	"testing"
+
+	"github.com/apache/dubbo-go/common/constant"
+	"github.com/apache/dubbo-go/protocol/invocation"
+	"github.com/opentracing/opentracing-go"
+	"github.com/opentracing/opentracing-go/mocktracer"
+	"github.com/stretchr/testify/assert"
+)
+
+// test rebuild the ctx
+func TestRebuildCtx(t *testing.T) {
+	opentracing.SetGlobalTracer(mocktracer.New())
+	attach := make(map[string]string, 10)
+	attach[constant.VERSION_KEY] = "1.0"
+	attach[constant.GROUP_KEY] = "MyGroup"
+	inv := invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
+
+	// attachment doesn't contains any tracing key-value pair,
+	ctx := rebuildCtx(inv)
+	assert.NotNil(t, ctx)
+	assert.Nil(t, ctx.Value(constant.TRACING_REMOTE_SPAN_CTX))
+
+	span, ctx := opentracing.StartSpanFromContext(ctx, "Test-Client")
+
+	opentracing.GlobalTracer().Inject(span.Context(), opentracing.TextMap,
+		opentracing.TextMapCarrier(inv.Attachments()))
+	// rebuild the context success
+	inv = invocation.NewRPCInvocation("MethodName", []interface{}{"OK", "Hello"}, attach)
+	ctx = rebuildCtx(inv)
+	span.Finish()
+	assert.NotNil(t, ctx)
+	assert.NotNil(t, ctx.Value(constant.TRACING_REMOTE_SPAN_CTX))
+}
+
+// rebuildCtx rebuild the context by attachment.
+// Once we decided to transfer more context's key-value, we should change this.
+// now we only support rebuild the tracing context
+func rebuildCtx(inv *invocation.RPCInvocation) context.Context {
+	ctx := context.WithValue(context.Background(), "attachment", inv.Attachments())
+
+	// actually, if user do not use any opentracing framework, the err will not be nil.
+	spanCtx, err := opentracing.GlobalTracer().Extract(opentracing.TextMap,
+		opentracing.TextMapCarrier(inv.Attachments()))
+	if err == nil {
+		ctx = context.WithValue(ctx, constant.TRACING_REMOTE_SPAN_CTX, spanCtx)
+	}
+	return ctx
+}
diff --git a/remoting/getty/readwriter.go b/remoting/getty/readwriter.go
index b59d9b82fb9f961da4be435cd717c857e1f79e5e..1aed516a3a9bca3f5f6ab82fe32fa6e981ee1e0b 100644
--- a/remoting/getty/readwriter.go
+++ b/remoting/getty/readwriter.go
@@ -18,18 +18,15 @@
 package getty
 
 import (
-	"github.com/apache/dubbo-go/remoting"
 	"reflect"
-)
 
-import (
-	"github.com/apache/dubbo-go-hessian2"
+	"github.com/apache/dubbo-go/remoting"
+
+	hessian "github.com/apache/dubbo-go-hessian2"
 	"github.com/dubbogo/getty"
-	perrors "github.com/pkg/errors"
-)
 
-import (
 	"github.com/apache/dubbo-go/common/logger"
+	perrors "github.com/pkg/errors"
 )
 
 ////////////////////////////////////////////
@@ -49,17 +46,16 @@ func NewRpcClientPackageHandler(client *Client) *RpcClientPackageHandler {
 func (p *RpcClientPackageHandler) Read(ss getty.Session, data []byte) (interface{}, int, error) {
 	//pkg := &DubboPackage{}
 	//p.client.ExchangeClient.GetPendingResponse(remoting.SequenceType())
-	resp, length, err := (p.client.codec).DecodeResponse(data)
+	resp, length, err := (p.client.codec).Decode(data)
 	//err := pkg.Unmarshal(buf, p.client)
 	if err != nil {
-		originErr := perrors.Cause(err)
-		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
+		if err == hessian.ErrHeaderNotEnough || err == hessian.ErrBodyNotEnough {
 			return nil, 0, nil
 		}
 
 		logger.Errorf("pkg.Unmarshal(ss:%+v, len(@data):%d) = error:%+v", ss, len(data), err)
 
-		return nil, length, perrors.WithStack(err)
+		return nil, length, err
 	}
 	//if pkg.Header.Type&hessian.PackageRequest == 0x00 {
 	//	pkg.Err = pkg.Body.(*hessian.Response).Exception
@@ -103,18 +99,17 @@ func NewRpcServerPackageHandler(server *Server) *RpcServerPackageHandler {
 }
 
 func (p *RpcServerPackageHandler) Read(ss getty.Session, data []byte) (interface{}, int, error) {
-	req, length, err := (p.server.codec).DecodeRequest(data)
+	req, length, err := (p.server.codec).Decode(data)
 	//resp,len, err := (*p.).DecodeResponse(buf)
 
 	if err != nil {
-		originErr := perrors.Cause(err)
-		if originErr == hessian.ErrHeaderNotEnough || originErr == hessian.ErrBodyNotEnough {
+		if err == hessian.ErrHeaderNotEnough || err == hessian.ErrBodyNotEnough {
 			return nil, 0, nil
 		}
 
 		logger.Errorf("pkg.Unmarshal(ss:%+v, len(@data):%d) = error:%+v", ss, len(data), err)
 
-		return nil, 0, perrors.WithStack(err)
+		return nil, 0, err
 	}
 
 	return req, length, err