2014-06-10 15:32

当struct具有嵌套struct时,golang rpc不返回



moving from gob encoding to json fixed the issue. However I would still like to know why this was failing to work with gob.

so my client code looks like this

account := new(database.Account)

err := client.Call("AccountDb.FindAccount", "username", account)

if err != nil {


On the server side AccountDb.FindAccount looks like this

func (t *AccountDb) FindAccount(args *string, reply *Account) error {

    reply.Username = "this is a test"

    return nil

The struct for Account looks like this

type Account struct {
    Id           int
    Username     string
    Password     string
    Email        string
    Created      time.Time
    LastLoggedIn time.Time
    AccessLevel  int

    Banned struct {
        reason  string
        expires time.Time

if I attempt to perform the rpc the requests starts and the server executes the procedure. However the program then hangs and the procedure does not return! If however I remove the Banned anonymous struct from the Account struct it works fine! Why is this? is there a solution to this problem?

edit the client and server register code looks like this


client, err = rpc.DialHTTP("tcp", "")

if err != nil {


defer db.Close()

account := new(database.AccountDb)
account.Database = db

l, e := net.Listen("tcp", ":9001")

if e != nil {
    logger.FATAL.Fatal("listen error:", e)
http.Serve(l, nil)
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答


  • dr5648 dr5648 7年前

    Evidently, the gob encoder fails to marshal the RPC response because the Banned struct has no exported fields. This playground example exhibits the error:

    encode error: gob: type struct { reason string; expires time.Time } 
    has no exported fields

    If you export the reason/expires fields by capitalizing them, the gob round-trip works OK (see http://play.golang.org/p/YrYFsk6trQ).

    The JSON encoder also requires that serialized fields are exported, but it does not return an error if a struct has none. The decode just returns default/zero values. Run http://play.golang.org/p/OBBkB4tPcZ and note that the Banned information is lost on the round-trip.

    If you need to detect these kinds of errors in the rpc package, there are two options:

    1. Edit rpc/debug.go, set the logDebug flag to true, and rebuild the rpc package, or
    2. Implement a ServerCodec that wraps the existing implementation and logs any errors returned by ReadRequestBody/WriteResponse.
    点赞 评论 复制链接分享