Java Jackson的套接字上的Json
我试图让两个应用程序通过TCP和基于JSON的消息进行通信。为此,我使用了杰克逊图书馆(1.9.4)。客户端只需打开一个套接字,然后侦听来自服务器的所有传入消息。看起来是这样的:Java Jackson的套接字上的Json,java,json,sockets,jackson,Java,Json,Sockets,Jackson,我试图让两个应用程序通过TCP和基于JSON的消息进行通信。为此,我使用了杰克逊图书馆(1.9.4)。客户端只需打开一个套接字,然后侦听来自服务器的所有传入消息。看起来是这样的: ObjectMapper mapper = new ObjectMapper().configure( Feature.AUTO_CLOSE_SOURCE, false); final ObjectReader reader = mapper.reader(Message.class); So
ObjectMapper mapper = new ObjectMapper().configure(
Feature.AUTO_CLOSE_SOURCE, false);
final ObjectReader reader = mapper.reader(Message.class);
Socket s = new Socket("192.168.1.102", 32000);
final Reader in = new InputStreamReader(socket.getInputStream());
while (true) {
Message message = reader.readValue(in);
process(message)
}
因此,读取器阻塞并等待消息完成,以解析和处理它。
我的问题是,有时阅读时会跳过一些消息。如果服务器发送msg1
、msg
和msg3
,则msg2
可能丢失,但读取msg3
没有问题
更奇怪的是,这种情况并不总是发生,但大约有50%。客户机和服务器都是单线程的,所以没有其他人可以访问套接字。我知道消息到达的事实,我试着用nc
模拟客户端,传入的消息总是正确的,所以我知道是在阅读时
由于它是一个TCP套接字,它们到达的顺序是有保证的,因此我怀疑ObjectReader
正在默默地丢弃一些东西,而没有抛出任何异常
有人知道会发生什么事吗?欢迎有任何想法!:) 差不多找到了
readValue()
方法只要在参考底图Reader
上每次调用read时都能得到完整的JSON消息,就可以正常工作
因为我是从套接字读取的,所以有时候read()
方法返回的消息不完整,而ObjectReader
无法正确处理。这很奇怪,因为在读取之前,ReaderBasedParser
类有一个while()
,所以它应该只在整个消息都在那里时返回
当我有时间的时候,我会仔细看一看。一个建议:不要做一个读者,按原样传递InputStream。构建阅读器没有任何好处,而且速度稍微慢一点。不确定这是否有助于解决问题本身,但杰克逊肯定会在必要时阻止阅读 然而,最有可能发生的情况是,由于底层的
JsonParser
进行缓冲(出于性能原因),缓冲数据不会返回(因为无法将数据“返回”到输入流或读取器)
JsonParser
确实有访问这些额外缓冲数据的方法,但解决此问题的最简单方法是显式创建JsonParser
(通过JsonFactory
),并将其传递给ObjectReader
,而不是要求ObjectReader
创建一个。这样,将使用相同的解析器,并使用它缓冲的数据。这也可能稍微快一点,因为没有每个解析器的创建开销
还有一种替代方法:查看
ObjectReader.readValues()
(注意其中的-s),它非常方便,工作方式与手动创建和传递解析器的方式几乎相同。什么是reader
,什么是readValue()
?reader是来自Jackson库的ObjectReader,它应该读取传入的消息并对其进行解析(这是在readValue()方法中完成的)我一直在读废话,直到我意识到你就是StaxMan:D我尝试重用JsonParser,它似乎已经解决了问题,谢谢你,没问题!也许我应该把名字改成@MrJackson
:-)最终全面解决了这个问题?@Garikai,不能说,又过了一段时间,新版本可能不再适用了,对不起,不用担心,最终解决了我的问题:)