Related samples:
In current Dubbo Go, the protocol layer is the bridge between the invocation model and the wire protocol. It is responsible for exposing providers as network services and turning consumer-side references into callable remote invokers.
The current protocol interface is defined in protocol/base/base_protocol.go:
type Protocol interface {
Export(invoker Invoker) Exporter
Refer(url *common.URL) Invoker
Destroy()
}
Its responsibilities are straightforward:
Export: expose a provider-side invoker as a network serviceRefer: create a consumer-side invoker for a target URLDestroy: destroy protocol-owned invokers and exportersThere is also an optional capability:
type RegistryUnregisterer interface {
UnregisterRegistries()
}
which is used during graceful shutdown so a protocol can unregister exported services from registries before full teardown.
On the provider side, Dubbo Go usually follows this path:
server.Register(...) or server.RegisterService(...) creates service metadata and an invoker.ServiceOptions.Export() selects protocol and registry behavior.Export(invoker).Different protocols provide different transports and codecs, but they all fit into the same Export contract.
On the consumer side:
client.Dial...(...) builds a reference.Refer(url).This is why the protocol layer is shared by both generated clients and registry-driven references.
Common built-in implementations include:
protocol/tripleprotocol/dubboprotocol/restprotocol/jsonrpcTriple is the recommended protocol for new applications. It supports unary and streaming calls, metadata headers and trailers, reflection, and gRPC interoperability on the wire.
rpc/multi-protocols is a good sample to read when you want to see how one application exposes multiple protocol endpoints at the same time.
Dubbo Go also has a registry-backed protocol layer under registry/protocol.
This wrapper coordinates:
So in practice, many service references are not “protocol only”; they are “registry protocol + concrete business protocol”.
The raw protocol implementation is often wrapped again through protocol/protocolwrapper, especially for filter chaining. That makes protocol invocation one of the main integration points for cross-cutting behaviors such as:
This layered structure is why the protocol package is small at the interface level but very important in the runtime call path.