英文:
Could not `chan` pass through RPC in Go?
问题
对于以下代码,通过RPC获取消息,为什么它的Done字段是nil?
chan
能通过RPC传递吗?
type Message struct {
Text string
Done chan bool
}
type (
GetArgs struct {
Key string
}
GetReply struct {
Message *Message
}
)
// 客户端
func connect() *rpc.Client {
client, err := rpc.Dial("tcp", ":1234")
if err != nil {
log.Fatal("dialing:", err)
}
return client
}
func get(key string) *Message {
client := connect()
args := GetArgs{key}
reply := GetReply{}
err := client.Call("KV.Get", &args, &reply)
if err != nil {
log.Fatal("error:", err)
}
client.Close()
return reply.Message
}
// 服务器
type KV struct {
mu sync.Mutex
messages map[string]*Message
}
func server() {
kv := new(KV)
kv.messages = map[string]*Message{}
done := make(chan bool)
kv.messages["Jan"] = &Message{Text: "hello", Done: done}
rpcs := rpc.NewServer()
rpcs.Register(kv)
l, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("error:", err)
}
go func() {
for {
conn, err := l.Accept()
if err == nil {
go rpcs.ServeConn(conn)
} else {
break
}
}
l.Close()
}()
}
func (kv *KV) Get(args *GetArgs, reply *GetReply) error {
kv.mu.Lock()
defer kv.mu.Unlock()
val, ok := kv.messages[args.Key]
if ok {
reply.Message = val
}
return nil
}
func main() {
server()
fmt.Printf("get() -> %v\n", get("Jan"))
// 输出:
// get() -> &{hello <nil>}
}
英文:
For the following code, get Message via RPC, why its Done field is nil?
Could not chan
pass through RPC?
type Message struct {
Text string
Done chan bool
}
type (
GetArgs struct {
Key string
}
GetReply struct {
Message *Message
}
)
// Client
func connect() *rpc.Client {
client, err := rpc.Dial("tcp", ":1234")
if err != nil {
log.Fatal("dialing:", err)
}
return client
}
func get(key string) *Message {
client := connect()
args := GetArgs{key}
reply := GetReply{}
err := client.Call("KV.Get", &args, &reply)
if err != nil {
log.Fatal("error:", err)
}
client.Close()
return reply.Message
}
// Server
type KV struct {
mu sync.Mutex
messages map[string]*Message
}
func server() {
kv := new(KV)
kv.messages = map[string]*Message{}
done := make(chan bool)
kv.messages["Jan"] = &Message{Text: "hello", Done: done}
rpcs := rpc.NewServer()
rpcs.Register(kv)
l, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("error:", err)
}
go func() {
for {
conn, err := l.Accept()
if err == nil {
go rpcs.ServeConn(conn)
} else {
break
}
}
l.Close()
}()
}
func (kv *KV) Get(args *GetArgs, reply *GetReply) error {
kv.mu.Lock()
defer kv.mu.Unlock()
val, ok := kv.messages[args.Key]
if ok {
reply.Message = val
}
return nil
}
func main() {
server()
fmt.Printf("get() -> %v\n", get("Jan"))
// Output:
// get() -> &{hello <nil>}
}
答案1
得分: 1
不。RPC参数只能是encoding/gob
可以序列化的类型,而通道不是其中之一。
函数和通道不会被发送到gob中。在顶层尝试编码这样的值将失败。chan或func类型的结构字段被视为未导出字段,并被忽略。
英文:
No. RPC arguments can only be those that are serializable by encoding/gob
, and chans are not one of them
> Functions and channels will not be sent in a gob. Attempting to encode such a value at the top level will fail. A struct field of chan or func type is treated exactly like an unexported field and is ignored.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论