J'ai du code avec lequel j'ai été exporté et je suis actuellement déconcentré - j'ai déjà travaillé avec RPC et le côté JSON, mais je n'arrive pas à le faire fonctionner sur RPC quand ça fonctionne bien localement.Unmarshal à un type d'interface
package main
import (
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"reflect"
)
type Foo interface {
SayHello() error
}
type fakeFoo struct {
internalValue string
}
func NewFakeFoo() *fakeFoo {
f := &fakeFoo{}
f.internalValue = "123456789"
return f
}
func (m *fakeFoo) SayHello() error {
return nil
}
type FooManager struct {
availableFoos []Foo
}
func NewFooManager() *FooManager {
p := new(FooManager)
p.availableFoos = make([]Foo, 0)
return p
}
func AddFoo(mm *FooManager, m Foo) {
mm.availableFoos = append(mm.availableFoos, m)
log.Println("Added type ", reflect.TypeOf(m))
}
func (mm *FooManager) GetAvailableFoos(in []Foo, out *[]Foo) error {
log.Println("availableFoos:", reflect.TypeOf(mm.availableFoos))
log.Println("*out is", reflect.TypeOf(*out))
*out = append(in, mm.availableFoos...)
log.Println("Out is:", reflect.TypeOf(*out))
return nil
}
func startServer(mm *FooManager) {
server := rpc.NewServer()
server.Register(mm)
l, e := net.Listen("tcp", ":8222")
if e != nil {
log.Fatal("listen error:", e)
}
for {
conn, err := l.Accept()
log.Println("Incoming!")
if err != nil {
log.Fatal(err)
}
go server.ServeCodec(jsonrpc.NewServerCodec(conn))
}
}
func main() {
fake1 := NewFakeFoo()
fooHolder := NewFooManager()
AddFoo(fooHolder, fake1)
go startServer(fooHolder)
log.Println("Using standard function call")
var foos []Foo
fooHolder.GetAvailableFoos(foos, &foos)
log.Println(foos)
log.Println("Using RPC call")
conn, err := net.Dial("tcp", "localhost:8222")
if err != nil {
log.Fatalln(err)
}
defer conn.Close()
c := jsonrpc.NewClient(conn)
err = c.Call("FooManager.GetAvailableFoos", foos, &foos)
if err != nil {
log.Println(foos)
log.Fatal("GetAvailableFoos error:", err)
}
log.Println("Success: ", foos)
}
(! Aussi ici, mais pas tcp disponible urgh http://play.golang.org/p/HmK-K09D2J)
La sortie est assez surprenant que cela indique quelque chose de mal avec le rassemblement plutôt que les données réelles - Exécution en Wireshark je peux voir les données étant envoyées sous la forme correcte (j'ai eu du succès en utilisant une technique similaire dans une autre question) mais je ne peux pas, pour la vie de moi, arrêter de lancer des bogues de triage.
La sortie de l'exécution est la suivante:
2015/09/07 10:04:35 Added type *main.fakeFoo
2015/09/07 10:04:35 Using standard function call
2015/09/07 10:04:35 availableFoos: []main.Foo
2015/09/07 10:04:35 *out is []main.Foo
2015/09/07 10:04:35 Out is: []main.Foo
2015/09/07 10:04:35 [0x1870a540]
2015/09/07 10:04:35 Using RPC call
2015/09/07 10:04:35 Incoming!
2015/09/07 10:04:35 [0x1870a540]
2015/09/07 10:04:35 GetAvailableFoos error:json: cannot unmarshal object into Go value of type main.Foo
exit status 1
Est-ce que je manque un truc d'interface/type ou est-ce un bug dans le rassemblement de Go?
Je ne sais pas pourquoi cela fonctionnerait différemment à appeler mais se demander si elle est due au fait que fakeFoo a une internalValue qui arrête le travail de triage? – 17Twenty