【问题标题】:golang rpc not returning when struct has a nested struct当结构具有嵌套结构时,golang rpc不返回
【发布时间】:2014-07-31 10:56:44
【问题描述】:

更新

从 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)

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

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

    reply.Username = "this is a test"

    return nil
}

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
    }
}

如果我尝试执行 rpc,请求会启动并且服务器会执行该过程。但是程序然后挂起并且程序不返回!但是,如果我从 Account 结构中删除 Banned 匿名结构,它可以正常工作!为什么是这样?这个问题有解决方案吗?

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

客户

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

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

服务器

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)

【问题讨论】:

  • 您是否尝试过创建二级结构来保存Banned 字段信息?
  • 我刚刚试过这个,我遇到了同样的问题

标签: go rpc


【解决方案1】:

显然,gob 编码器无法编组 RPC 响应,因为 Banned 结构没有导出字段。这个playground example 显示错误:

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

如果您通过大写导出原因/过期字段,则 gob 往返工作正常(请参阅http://play.golang.org/p/YrYFsk6trQ)。

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

如果您需要检测rpc 包中的此类错误,有两种选择:

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2019-08-14
  • 1970-01-01
  • 2021-08-08
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多