2014-06-10 53 views
3

UPDATEgolang RPC未返回時struct包含嵌套結構

從料滴編碼移動到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 
} 

的結構爲帳戶看起來像這樣

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,請求開始並且服務器執行該過程。然而,程序然後掛起,程序不會返回!但是,如果我從帳戶結構中刪除禁止的匿名結構它工作正常!爲什麼是這樣?有沒有解決這個問題的方法?

編輯 客戶端和服務器註冊的代碼如下所示

客戶

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) 
+1

你有沒有試過創建一個輔助結構來保存'禁止的'字段信息? – nesv

+0

我剛剛嘗試過此操作,並且遇到同樣的問題 – zidsal

回答

7

顯然,採空區編碼器失敗元帥,因爲Banned結構中的RPC響應沒有導出的字段。這playground example展品錯誤:

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

如果導出的原因/通過資本它們到期領域,往返工程確定採空區(見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返回的任何錯誤。
+0

此行爲存在問題,請https://code.google.com/p/go/issues/detail?id=8173 – Wessie