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

时间:2015-01-12 05:19:55

标签: json tcp proxy go stream

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

以下是我采取的步骤:

  1. 拨打与远程服务器的连接
  2. 将单个json请求写入远程服务器(REQ)
  3. 从同一个远程服务器读取单个json回复(完成代理握手REPLY)
  4. 在有效的json握手时,将客户端连接传递到代码的另一部分,从那时起(将继续)切换到基于文本的协议。
  5. 问题是,当json.Decoder将数据读入其内部缓冲区时,它可能可能读取的数据超过了需要的数据json.Decoder has a Buffered()方法,它返回一个io.Reader。剩下的数据。

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

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

    非常感谢任何见解。

1 个答案:

答案 0 :(得分:0)

你可以尝试

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)
}