我正在学习本教程:
https://github.com/libp2p/go-libp2p-examples/tree/master/chat-with-mdns
它的简短形式如下:
stream, err := host.NewStream(ctx, peer.ID, protocol.ID(cfg.ProtocolID))
之后,创建了一个缓冲区流/读-写变量:
rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))
现在,这个流用于在对等点之间发送和接收数据。这是使用两个具有rw作为输入的goroutine函数来完成的:
go writeData(rw) go readData(rw)
我的问题是:
我想过那些解决办法。但我对歌朗并不熟悉,所以也许你有一个更好的:
stream, err := host.NewStream(ctx, peer.ID, protocol.ID(cfg.ProtocolID))rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))谢谢你帮忙解决这个问题!
发布于 2019-03-25 16:42:48
这就是readData从您的教程中所做的:
func readData(rw *bufio.ReadWriter) {
for {
str, err := rw.ReadString('\n')
if err != nil {
fmt.Println("Error reading from buffer")
panic(err)
}
if str == "" {
return
}
if str != "\n" {
// Green console colour: \x1b[32m
// Reset console colour: \x1b[0m
fmt.Printf("\x1b[32m%s\x1b[0m> ", str)
}
}
}它基本上会读取流,直到它找到一个\n,这是一个新的行字符,并将其打印到stdout。
The writeData
func writeData(rw *bufio.ReadWriter) {
stdReader := bufio.NewReader(os.Stdin)
for {
fmt.Print("> ")
sendData, err := stdReader.ReadString('\n')
if err != nil {
fmt.Println("Error reading from stdin")
panic(err)
}
_, err = rw.WriteString(fmt.Sprintf("%s\n", sendData))
if err != nil {
fmt.Println("Error writing to buffer")
panic(err)
}
err = rw.Flush()
if err != nil {
fmt.Println("Error flushing buffer")
panic(err)
}
}
}它从stdin中读取数据,这样您就可以键入消息,并将其写入rw并刷新它。这种方式可以进行一种tty聊天。如果它正常工作,您应该能够启动至少两个对等点,并通过stdin进行通信。
您不应该为新内容重新创建新的rw。您可以重用现有的,直到您关闭它。从tuto的代码中,为每个新的对等体创建一个新的rw。
现在,tcp流不作为http请求与该请求对应的请求和响应一起工作。因此,如果您想发送什么,并获得对该特定问题的答复,您可以发送以下格式的消息:
[8 bytes unique ID][content of the message]\n当您收到它时,解析它,准备响应并以相同的格式发送它,这样您就可以匹配消息,创建一种请求/响应通信。
你可以这样做:
func sendMsg(rw *bufio.ReadWriter, id int64, content []byte) error {
// allocate our slice of bytes with the correct size 4 + size of the message + 1
msg := make([]byte, 4 + len(content) + 1)
// write id
binary.LittleEndian.PutUint64(msg, uint64(id))
// add content to msg
copy(msg[13:], content)
// add new line at the end
msg[len(msg)-1] = '\n'
// write msg to stream
_, err = rw.Write(msg)
if err != nil {
fmt.Println("Error writing to buffer")
return err
}
err = rw.Flush()
if err != nil {
fmt.Println("Error flushing buffer")
return err
}
return nil
}
func readMsg(rw *bufio.ReadWriter) {
for {
// read bytes until new line
msg, err := rw.ReadBytes('\n')
if err != nil {
fmt.Println("Error reading from buffer")
continue
}
// get the id
id := int64(binary.LittleEndian.Uint64(msg[0:8]))
// get the content, last index is len(msg)-1 to remove the new line char
content := string(msg[8:len(msg)-1])
if content != "" {
// we print [message ID] content
fmt.Printf("[%d] %s", id, content)
}
// here you could parse your message
// and prepare a response
response, err := prepareResponse(content)
if err != nil {
fmt.Println("Err while preparing response: ", err)
continue
}
if err := s.sendMsg(rw, id, response); err != nil {
fmt.Println("Err while sending response: ", err)
continue
}
}
}希望这能有所帮助。
https://stackoverflow.com/questions/55340599
复制相似问题