Джсон над гнездом с Джексоном - PullRequest
1 голос
/ 14 февраля 2012

Я пытаюсь заставить два приложения взаимодействовать через TCP с сообщениями на основе JSON.Для этого я использую библиотеку Джексона (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)
}

Таким образом, считыватель блокирует и ждет, пока сообщение не будет завершено, чтобы проанализировать его и обработать.Моя проблема в том, что иногда некоторые сообщения пропускаются при чтении.Если сервер отправляет msg1, msg и msg3, возможно, msg2 потеряно, но msg3 читается без проблем.

Чтобы сделать это страннее, этого не происходитвсе время, но около 50%.И клиент, и сервер являются однопоточными, поэтому никто больше не имеет доступа к сокету.И я точно знаю, что сообщения приходят, я пытался смоделировать клиента с помощью nc, и входящие сообщения всегда верны, поэтому я знаю, что это при чтении.

Поскольку это сокет TCP, порядок, в котором они прибыли, гарантирован, поэтому я подозреваю, что ObjectReader молча отбрасывает некоторые вещи без каких-либо исключений.ключ к тому, что может происходить?Любые мысли приветствуются!:)

Ответы [ 2 ]

1 голос
/ 14 февраля 2012

Одно предложение: не создавайте Reader, просто передайте InputStream как есть.Нет смысла создавать Reader, и он немного медленнее.Не уверен, поможет ли это самой проблеме, но Джексон определенно заблокирует чтение, когда это будет необходимо.

Однако, скорее всего, произойдет следующее: поскольку базовый JsonParser выполняет буферизацию (по соображениям производительности),буферизованные данные не возвращаются (поскольку нет способа «вернуть» данные во входной поток или считыватель).

JsonParser имеет методы для доступа к таким дополнительным буферизованным данным, но самый простой способ решить эту проблемупроблема заключается в том, чтобы явно создать JsonParser (через JsonFactory) и передать его в ObjectReader, а не просить ObjectReader создать его.Таким образом, будет использоваться тот же парсер и буферизованные данные.Это также может быть немного быстрее, так как нет затрат на создание парсера.

Еще один альтернативный метод: проверьте ObjectReader.readValues() (обратите внимание на -s там), который удобен и работает почти так жеСпособ создания и передачи парсера вручную.

0 голосов
/ 14 февраля 2012

Вид нашел его.

Метод readValue() просто работает правильно, если при каждом вызове read на нижележащем элементе Reader он получает полное сообщение JSON.

Поскольку я читал из сокета, иногда случалось, что метод read() возвращал меньше, чем полное сообщение, и ObjectReader не мог обработать его должным образом. Что странно, потому что класс ReaderBasedParser имеет while() перед чтением, поэтому он должен возвращаться только тогда, когда все сообщение есть.

Присмотрится, когда у меня будет время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...