gpt4 book ai didi

java - 与 Jackson 通过 Socket 进行 Json

转载 作者:太空宇宙 更新时间:2023-11-04 08:22:26 25 4
gpt4 key购买 nike

我正在尝试让两个应用程序通过 TCP 使用基于 JSON 的消息进行通信。为此,我使用 Jackson 库(1.9.4)。客户端只需打开一个套接字,然后监听来自服务器的所有传入消息。它看起来像这样:

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

因此,读取器会阻塞并等待,直到消息完成才能解析并处理它。我的问题是,有时阅读时会跳过一些消息。如果服务器发送 msg1msgmsg3,可能 msg2 丢失,但 msg3 读取没有问题。

更奇怪的是,这种情况并不总是发生,但大约有 50% 发生。客户端和服务器都是单线程的,因此没有其他人可以访问套接字。我知道消息到达的事实,我尝试用 nc 模拟客户端,并且传入的消息总是正确的,所以我知道这是在阅读时。

由于它是一个 TCP 套接字,因此它们到达的顺序是有保证的,所以我怀疑 ObjectReader 正在默默地丢弃一些东西而不抛出任何异常。

有人知道会发生什么吗?欢迎任何想法! :)

最佳答案

一个建议:不要创建 Reader,只需按原样传递 InputStream 即可。构建Reader没有任何好处,而且速度稍微慢一些。不确定这是否有助于解决问题本身,但 jackson 肯定会在必要时阻止读取。

但是,最有可能发生的情况是,由于底层 JsonParser 会进行缓冲(出于性能原因),因此不会返回缓冲的数据(因为无法将数据“返回”到输入流或读取器)。

JsonParser 确实有方法来访问此类额外的缓冲数据,但解决此问题的最简单方法是显式创建 JsonParser(通过 JsonFactory),并将其传递给 ObjectReader,而不是要求 ObjectReader 创建一个。这样,将使用相同的解析器,并使用它缓冲的数据。这也可能会稍微快一些,因为没有每个解析器的创建开销。

还有一种替代方法:查看 ObjectReader.readValues() (请注意其中的 -s),这很方便,并且与手动创建和传递解析器的方式几乎相同。

关于java - 与 Jackson 通过 Socket 进行 Json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9267669/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com