Ответ 1
Я кодифицировал то, что делают я и некоторые другие разработчики:
http://en.wikipedia.org/wiki/Line_Delimited_JSON
Это имеет преимущество, заключающееся в совместимости с netcat/telnet.
Смотрите также: http://ndjson.org/
Я пишу простой потоковый сервис JSON. Он состоит из сообщений JSON, отправляемых с перерывами в течение длительного периода времени (недели или месяцы).
Какова наилучшая практика в отношении отправки нескольких сообщений JSON через обычный сокет TCP?
Некоторые альтернативы, на которые я смотрел (и их недостатки):
Есть ли хороший или, по крайней мере, устоявшийся способ сделать это?
Я кодифицировал то, что делают я и некоторые другие разработчики:
http://en.wikipedia.org/wiki/Line_Delimited_JSON
Это имеет преимущество, заключающееся в совместимости с netcat/telnet.
Смотрите также: http://ndjson.org/
мои первые два варианта:
Сделайте то, что делают ранние протоколы TCP: отправьте одно сообщение (объект JSON в вашем случае) и закройте соединение. Клиент обнаруживает его и снова открывает, чтобы получить следующий объект.
Выполняйте то, что делает HTTP-код в chunk-mode: сначала отправляйте количество байтов в объекте JSON, новую строку (CRLF в HTTP) и ваш объект JSON. Клиент просто должен подсчитывать байты, чтобы знать, когда следующий байт будет следующим объективом.
Если вы хотите обслуживать клиентов браузера, наиболее близким к необработанному TCP является WebSockets.
WebSockets имеет достаточный импульс, чтобы поставщики браузеров улучшали поддержку (Chrome 14 и Firefox 7/8 поддерживают последний протокол), и что поддержка этого будет широким спектром клиентских и серверных фреймворков.
Уже существует несколько клиентских библиотек с открытым исходным кодом, включая Autobahn WebSocket.
Если вы хотите испечь что-то для своего собственного (поверх чистого TCP), я бы рекомендовал формат с префиксом длины для ваших сообщений JSON, т.е. Netstrings
Отказ от ответственности: я автор Autobahn и работаю в Tavendo.
Вы можете использовать Server-Sent Events.
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');
};
Первый из четырех байтов сообщения может быть 32-разрядным целым числом, указывающим размер (в байтах) сообщения. Затем получатель должен выполнить следующие действия:
Код отправителя в С#:
public void WriteMessage(Packet packet) {
// Convert the object to JSON
byte[] message = Encoding.UTF8.GetBytes(packet.Serialize());
// Serialize the number of characters
byte[] messageLength = BitConverter.GetBytes(message.Length);
// Build the full message that will hold both the size of the message and the message itself
byte[] buffer = new byte[sizeof(int) + message.Length];
Array.Clear(message, 0, message.Length);
// Print the size into the buffer
for (int i = 0; i < sizeof(int); i++)
{
buffer[i] = messageLength[i];
}
// Print the message into the buffer
for (int i = 0; i < message.Length; i++)
{
buffer[i + sizeof(int)] = message[i];
}
// Send it
stream.Write(buffer, 0, buffer.Length);
}