如何使用 json.Decoder 解码单个 json 消息并将连接切换到不同的协议?

How can I use json.Decoder to decode a single json message and switch the connection to a different protocol going foward?

我正在开发一个基于 TCP 的代理,它必须首先在给定连接上 json 中进行 REQ/REPLY 握手。因为 JSON 是一个自我定界协议,所以我使用 Go 的 json.Decoder 来完成这项工作,它做得很好。

以下是我采取的步骤:

  1. 拨号连接到远程服务器
  2. 向远程服务器 (REQ) 写入单个 json 请求
  3. 从同一远程服务器读取单个 json 回复(完成代理握手回复)
  4. 在有效的 json 握手后,将客户端连接传递到代码的另一部分,该代码将从此时开始(继续)切换到基于文本的协议。

问题是,当 json.Decoder 将数据读入其内部缓冲区时,它 可能 读取比其需要更多的数据,在这种情况下 json.Decoder has a Buffered() 方法它返回一个 io.Reader 和剩余的数据。

此数据(在 Buffered() 方法中可用)现在是基于文本的协议数据,需要在 json 握手完成工作后从连接中读取。但是,如果我按原样向前传递连接而不考虑剩余缓冲区,则连接会进入锁定状态,因为它正在等待读取永远不会到来的数据。处理基于文本的协议的代码 期望 一个 net.Conn 前进,一旦我向前传递连接(在 json 握手之后)使用连接的代码现在知道如何使用基于文本的协议。所以应该有明确的工作界限。

我的问题是解决这个问题的理想方法是什么,这样我仍然可以利用 json.Decoder,但要确保当我将连接传递到代理中代码的不同部分时,我知道基于文本的协议的数据的开始仍然是可读的。我需要以某种方式获取 json.Decoder 的 Buffered() 方法中的剩余数据,并将其放回连接前面,以便以后可以正确读取它。

非常感谢任何见解。

你可以试试

type ConnWithBuffIncluded struct{ //Implement net.Conn so can be passed through pipeline
    net.Conn
    json.Decoder
}

func (x ConnWithBuffIncluded) Read(p []byte) (n int, err error){ //Will Read both sources
    return io.MultiReader(x.Decoder.Buffered(), x.Conn).Read(p)
}