假设我有一个应用程序,在后端我想使用原始tcp,以便我可以在不同的服务之间进行双向通信。在这个应用程序中,我希望通过一个由json对象组成的有效负载发送,当发送json数据时,每隔几条消息,它就会被切断,剩下的就会聚集到下一个响应中。由于从http升级所用的时间,我不想使用像websockets这样的东西。确保json对象来自一个节点并从另一个节点读取为整个 json对象的好方法(并且希望是最好的)是什么?
我知道发送和接收设置大小的缓冲区和心跳消息是经验法则,但我能看到一个例子吗?最好是在Javascript(node的net stdlib)或Golang(它是net stdlib),因为那些是我最熟练的语言,尽管我并不关心它最终用的是什么语言。
(我知道有几个问题在询问有关确保使用tcp传递消息的相似事项,但没有人要求我找到一个例子)
我知道tcp是一个流。我只想问一种方法来确保在将特定的json对象写入此流时,如何确保在另一端获得相同的json对象,如“从节点a发送json对象X,ok节点b收到同一个对象 X“
答案 0 :(得分:4)
您不需要心跳或固定大小的消息来确认递送。如果您需要确保交付,则需要申请级别确认。如果您需要确保传递正确的消息,则需要包含唯一的消息ID以进行确认。如果您需要确保邮件未被更改,则需要包含校验和或MAC。
这听起来好像你在消息框架方面遇到了麻烦。虽然有很多方法来构建您的消息(简单的长度前缀,type-length-value,HTTP / 1.1等),但一个简单的解决方案是使用内置的json.Encoder
和json.Decoder
示例客户端,发送" PING"消息每秒:
type Message struct {
Payload string
}
func sendMessages(c net.Conn) {
message := Message{}
encoder := json.NewEncoder(c)
for i := 0; ; i++ {
message.Payload = fmt.Sprintf("PING %d", i)
err := encoder.Encode(message)
if err != nil {
log.Fatal(err)
}
time.Sleep(time.Second)
}
}
示例服务器:
type Message struct {
Payload string
}
func receiveMessages(c net.Conn) {
m := Message{}
decoder := json.NewDecoder(c)
for {
err := decoder.Decode(&m)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Received: %#v\n", m)
}
}