我正在尝试使用libchan库在使用类似 go 通道的传输的机器之间发送消息。
根据我收集到的信息,粗略的想法是这样的:
- 你有一个 SPDY 客户端,它通过 tcp 向一个地址发送一个序列化的命令对象。此命令对象包含一个名为 a 的 libchan 通道
Pipe
,通过该通道发送响应。 - 当服务器接收到一个传入连接时,它会等待一个命令对象。
Pipe
当它得到一个时,它会通过包含在对象中的内容发送响应。
这是我的困惑点。要让通道在两台机器之间持续存在,它们必须共享内存或至少共享连接它们两者的抽象。根据我对 libchan 代码库的了解,我不知道这怎么可能。
这是 repo 中示例的片段:
// client
receiver, remoteSender := libchan.Pipe()
command := &RemoteCommand{
Cmd: os.Args[1],
Args: os.Args[2:],
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
StatusChan: remoteSender,
}
err = sender.Send(command)
if err != nil {
log.Fatal(err)
}
err = receiver.Receive(response)
if err != nil {
log.Fatal(err)
}
os.Exit(response.Status)
和服务器:
// server
t := spdy.NewTransport(p)
go func() {
for {
receiver, err := t.WaitReceiveChannel()
if err != nil {
log.Print("receiver error")
log.Print(err)
break
}
log.Print("about to spawn receive proc")
go func() {
for {
command := &RemoteReceivedCommand{}
err := receiver.Receive(command)
returnResult := &CommandResponse{}
if res != nil {
if exiterr, ok := res.(*exec.ExitError); ok {
returnResult.Status = exiterr.Sys().
(syscall.WaitStatus).ExitStatus()
} else {
log.Print("res")
log.Print(res)
returnResult.Status = 10
}
}
err = command.StatusChan.Send(returnResult)
我要磨练的重点在这里:
libchan.Pipe()
根据消息来源,这将返回一个通道。一个引用保存在客户端,另一个发送到服务器。然后使用此通道将值从后者传递到前者。这在实践中如何运作?