Tars Tutorial for Go Developers – Communication Modes, Server and Client Implementation
This tutorial explains how Go developers can generate Tars RPC code from IDL, implement server and client logic, configure server and client settings, use various call patterns such as context, one‑way, mod‑hash and consistent‑hash, and quickly scaffold projects with the tarsgo tool.
This article is the second part of the "Tars tutorial for Go developers" series, focusing on communication modes and the implementation of both server and client components.
Example IDL
module order {
struct Order {
1 require string id;
2 optional vector
items;
3 optional string description;
4 require float price;
5 optional string destination;
};
interface OrderManagement {
Order getOrder(string orderId);
};
};Generating Go protocol code
tars2go -outdir=. \
-module=github.com/lbbniu/TarsGo-tutorial \
proto/order.tarsThe generated files are placed under order and proto directories.
Server Implementation
Service definition
interface OrderManagement {
Order getOrder(string orderId);
}; type OrderManagementServant interface {
GetOrder(orderId string) (ret Order, err error)
}
type OrderManagementServantWithContext interface {
GetOrder(tarsCtx context.Context, orderId string) (ret Order, err error)
}The business logic implements the above interface:
package servant
import (
"context"
"net/http"
"github.com/TarsCloud/TarsGo/tars"
"github.com/lbbniu/TarsGo-tutorial/order"
)
var orders = make(map[string]order.Order)
type OrderCtx struct{}
var _ order.OrderManagementServantWithContext = (*OrderCtx)(nil)
func NewOrderCtx() *OrderCtx {
o := &OrderCtx{}
o.init()
return o
}
func (o *OrderCtx) init() {
orders["1"] = order.Order{Id: "1", Price: 100, Items: []string{"iPhone 11", "MacBook Pro"}, Description: "MacBook Pro", Destination: "Beijing"}
}
func (o *OrderCtx) GetOrder(tarsCtx context.Context, orderId string) (ret order.Order, err error) {
ord, exists := orders[orderId]
if exists {
return ord, nil
}
return ord, tars.Errorf(http.StatusNotFound, "Order does not exist. : ", orderId)
}Starting the server:
package main
import (
"github.com/TarsCloud/TarsGo/tars"
"github.com/lbbniu/TarsGo-tutorial/internal/servant"
"github.com/lbbniu/TarsGo-tutorial/order"
)
func main() {
cfg := tars.GetServerConfig()
imp := new(servant.Order)
app := new(order.OrderManagement)
app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".orderObj")
tars.Run()
}Server configuration details
The tars.GetServerConfig() function returns a struct containing fields such as Node , App , Server , LogPath , Adapters , timeout settings, TLS options, and more. The article lists the most important fields and their meanings.
Configuration file
<tars>
<application>
<server>
app=Test
server=OrderServer
local=tcp -h 127.0.0.1 -p 10027 -t 30000
logpath=/tmp
<Test.OrderServer.OrderObjAdapter>
allow
endpoint=tcp -h 127.0.0.1 -p 8080 -t 60000
handlegroup=Test.OrderServer.OrderObjAdapter
maxconns=200000
protocol=tars
queuecap=10000
queuetimeout=60000
servant=Test.OrderServer.OrderObj
threads=1
</Test.OrderServer.OrderObjAdapter>
</server>
</application>
</tars>Client Implementation
The client can call the service without writing any protocol‑specific code.
Simple call (no context)
package main
import (
"fmt"
"github.com/TarsCloud/TarsGo/tars"
"github.com/lbbniu/TarsGo-tutorial/order"
)
func main() {
comm := tars.GetCommunicator()
client := new(order.OrderManagement)
obj := "Test.OrderServer.OrderObj@tcp -h 127.0.0.1 -p 8080 -t 60000"
comm.StringToProxy(obj, client)
noCtxCall(client)
}
func noCtxCall(client *order.OrderManagement) {
order, err := client.GetOrder("1")
if err != nil {
panic(err)
}
fmt.Printf("noctx: %+v\n", order)
}Call with context
func ctxCall(client *order.OrderManagement) {
order, err := client.GetOrderWithContext(context.Background(), "1")
if err != nil {
panic(err)
}
fmt.Printf("ctx: %+v\n", order)
}One‑way call
// One‑way call, no return value
func oneWayCall(client *order.OrderManagement) {
_, err := client.GetOrderOneWayWithContext(context.Background(), "1")
if err != nil {
panic(err)
}
fmt.Println("oneway")
}Mod‑hash and consistent‑hash calls
func modHashCall(client *order.OrderManagement) {
ctx := current.ContextWithClientCurrent(context.Background())
var hashCode uint32 = 1
current.SetClientHash(ctx, int(tars.ModHash), hashCode)
order, err := client.GetOrderWithContext(context.Background(), "1")
if err != nil {
panic(err)
}
fmt.Printf("ModHash: %+v\n", order)
}
func consistentHashCall(client *order.OrderManagement) {
ctx := current.ContextWithClientCurrent(context.Background())
var hashCode uint32 = 1
current.SetClientHash(ctx, int(tars.ConsistentHash), hashCode)
order, err := client.GetOrderWithContext(context.Background(), "1")
if err != nil {
panic(err)
}
fmt.Printf("ConsistentHash: %+v\n", order)
}Client configuration
type clientConfig struct {
Locator string
Stat string
Property string
ModuleName string
RefreshEndpointInterval int
ReportInterval int
CheckStatusInterval int
KeepAliveInterval int
AsyncInvokeTimeout int
SyncInvokeTimeout int
ClientQueueLen int
ClientIdleTimeout time.Duration
ClientReadTimeout time.Duration
ClientWriteTimeout time.Duration
ClientDialTimeout time.Duration
ReqDefaultTimeout int32
ObjQueueMax int32
}The article also shows how to write a tarsgo scaffold command to generate a new project, the command used, and the resulting file tree.
Conclusion
After following the steps, developers can quickly build a complete TarsGo service, from IDL definition to server and client code, configuration, and project scaffolding.
TAL Education Technology
TAL Education is a technology-driven education company committed to the mission of 'making education better through love and technology'. The TAL technology team has always been dedicated to educational technology research and innovation. This is the external platform of the TAL technology team, sharing weekly curated technical articles and recruitment information.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.