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

zid*_*sal 2 rpc go

UPDATE

从gob编码转到json修复了这个问题.但是,我仍然想知道为什么这与gob无法合作.

所以我的客户端代码看起来像这样

account := new(database.Account)

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

if err != nil {
    logger.FATAL.Print(err.Error())
    return
}

logger.INFO.Print(account)
Run Code Online (Sandbox Code Playgroud)

在服务器端AccountDb.FindAccount看起来像这样

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

    reply.Username = "this is a test"

    return nil
}
Run Code Online (Sandbox Code Playgroud)

Account的结构看起来像这样

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
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试执行rpc请求开始,服务器执行该过程.然而程序然后挂起,程序不会返回!但是,如果我从Account结构中删除禁止的匿名结构,它工作正常!为什么是这样?有这个问题的解决方案吗?

编辑客户端和服务器注册码如下所示

客户

client, err = rpc.DialHTTP("tcp", "127.0.0.1:9001")

if err != nil {
    logger.FATAL.Panic(err.Error())
}
Run Code Online (Sandbox Code Playgroud)

服务器

defer db.Close()

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

rpc.Register(account)
rpc.HandleHTTP()
l, e := net.Listen("tcp", ":9001")

if e != nil {
    logger.FATAL.Fatal("listen error:", e)
}
http.Serve(l, nil)
Run Code Online (Sandbox Code Playgroud)

lnm*_*nmx 6

显然,gob编码器无法编组RPC响应,因为Bannedstruct没有导出的字段.此操场示例显示错误:

encode error: gob: type struct { reason string; expires time.Time } 
has no exported fields
Run Code Online (Sandbox Code Playgroud)

如果您通过大写它们来导出reason/expires字段,那么gob往返工作正常(请参阅http://play.golang.org/p/YrYFsk6trQ).

JSON编码器还要求导出序列化字段,但如果struct没有,则不会返回错误.解码只返回默认值/零值.运行http://play.golang.org/p/OBBkB4tPcZ并注意Banned往返时信息丢失.

如果您需要在rpc包中检测到这些类型的错误,有两种选择:

  1. 编辑rpc/debug.go,将logDebug标志设置为true,然后重建rpc包,或
  2. 实现一个ServerCodec包装现有实现并记录ReadRequestBody/ 返回的任何错误WriteResponse.