Выбор транспорта для JSON через TCP
Я пишу простой потоковый сервис JSON. Он состоит из сообщений JSON, отправляемых периодически, в течение длительного периода времени (недели или месяцы).
какова наилучшая практика в отношении отправки нескольких сообщений JSON через простой TCP-сокет?
некоторые альтернативы, которые я рассмотрел (и их недостатки):
- разделенные новой строкой JSON-downside: новые строки в JSON требуют экранирования или запрета
- WebSocket, которая вдохновила 0x00 0xFF framing-downside: теперь он двоичный, а не utf-8 больше
- real websockets-недостаток: отсутствие (opensource) websocket клиент библиотеки
- http multipart http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html - недостаток: неполная поддержка клиентов?
- нет разделителей-недостаток: chunking требует разбора JSON (не может просто считать кудри из-за кудрей в строках)
есть ли хороший, или на наименее устоявшийся способ сделать это?
4 ответов
мои первые два варианта будет:
-
сделайте то, что делают ранние протоколы TCP: отправьте одно сообщение (объект JSON в вашем случае) и закройте соединение. Клиент обнаруживает его и снова открывает, чтобы получить следующий объект.
- pros: очень легко разобрать, никаких дополнительных (содержание) байтов не отправлено. любая потеря данных означает потерю только одного объекта. если вы можете выдержать это, нет необходимости, чтобы добавить retransmision к вашему приложению.
- минусы: Если вы отправляете (огромный) много (очень) мелкие предметы, три пакета квитирования TCP добавляет к задержке.
-
сделайте то, что делает HTTP в режиме chunked: сначала отправьте количество байтов в объекте JSON, новую строку (CRLF в HTTP) и ваш объект JSON. Клиенту просто нужно подсчитать байты, чтобы знать, когда следующий байт будет следующим objectsize.
- плюсы: вы держите один долгоживущий поток.
- минусы: несколько дополнительных байтов, вы должны сохранить долгоживущий поток, так случайно перерыв и переподключение должны обрабатываться как исключительные события, нужно установить некоторое рукопожатие, чтобы продолжить, где это не удалось.
когда вы хотите обслуживать клиентов браузера, ближе всего к raw TCP является WebSockets.
WebSockets имеет достаточный импульс, что поставщики браузеров улучшат поддержку (Chrome 14 и Firefox 7/8 поддерживают последний проект протокола) и что широкий спектр клиентских и серверных фреймворков будет поддерживать его.
здесь are уже несколько клиентских библиотек с открытым исходным кодом, включая Автобан WebSocket.
когда вы хотите выпекайте что-нибудь для себя (поверх raw TCP), я бы рекомендовал формат с префиксом длины для ваших сообщений JSON, т. е. Netstrings
отказ от ответственности: я автор Autobahn и работа для Tavendo.
я систематизировал то, что я и некоторые другие разработчики делают:
http://en.wikipedia.org/wiki/Line_Delimited_JSON
оно имеет преимущество быть netcat / telnet совместимым.
см. также:http://ndjson.org/
можно использовать Сервер-Отправлено Событий.
var source = new EventSource('/EventSource');
source.onmessage = function(e) {
var data = JSON.parse(e.data);
console.log(e.data);
};
source.onopen = function(e) {
console.log('EventSource opened');
};
source.onerror = function(e) {
console.log('EventSource error');
};