Разбор потока HTML5 EventSource из сети

Я изучил спецификацию HTML5 EventSource и не могу понять, как анализировать и обрабатывать возврат каретки в конце полученных данных.

Приложение получает поток данных, состоящий из строк. Каждая строка может заканчиваться символами \r\n, \n или \r. В пустой строке событие должно считаться готовым и запускаться слушателям.

data: foobar\r\n
id: 1\r\n
\r\n

Одинаково значимое событие с тем же содержанием

data: foobar\n
id: 1\r\n
\r

Полная спецификация здесь, http://dev.w3.org/html5/eventsource/ Глава 6. описывает БНФ входа.

Проблема заключается в возврате каретки, когда он виден в конце полученных данных. Теперь, насколько я понимаю, правильный способ синтаксического анализа - выполнить поиск самого длинного совпадения и затем дождаться следующего пакета данных. Проблема в том, что если \r действительно был пустым маркером строки, событие не будет запущено до тех пор, пока не прибудет следующий пакет данных и парсер не наберет достаточно данных для попытки самого длинного совпадения.

Текущий пакет данных

data: foobar\r\n
id: 1\r\n
\r

Следующий пакет данных

\n
data: foobar2\r\n
id: 1\r\n
\r\n

Альтернативный кейс. Следующий пакет данных

data: foobar2\r\n
id: 1\r\n
\r\n

Это не было бы проблемой при традиционном синтаксическом анализе, но это в EventSource, потому что мне нужно инициировать события как можно скорее, поэтому, если реализация ожидает, пока следующий пакет данных получит самое длинное совпадение, он может ждать долгое время, если отправитель использовал один символ ' \r' в качестве пустого маркера строки, и какое-то время он больше ничего не отправит.


person Teemu Ikonen    schedule 29.11.2012    source источник


Ответы (1)


Интересная проблема! Я предполагаю, что вы не используете браузер, а пишете свой собственный клиент? (При написании кода на стороне сервера всегда отправляйте только \n или просто \r!!)

Решение состоит в том, чтобы при чтении из сокета преобразовать любую последовательность "\r\n" в "\r". Другими словами, как только вы получаете "\r", вы можете рассматривать его как конец строки, выполнять любую необходимую обработку и устанавливать флаг CR_just_received. Если вы получили "\n" и CR_just_received==true, то спокойно проглотите это. Убедитесь, что CR_just_received очищается всякий раз, когда принимается любой байт, кроме \r.

person Darren Cook    schedule 08.10.2013