我正在编写一个简单的流式JSON服务。它由间歇性发送的JSON消息组成,持续很长一段时间(数周或数月)。
通过普通TCP套接字发送多个JSON消息的最佳做法是什么?
我看过的一些替代方案(及其缺点)是:
有没有一种好的,或至少是完善的方法呢?
答案 0 :(得分:12)
我的前两个选项是:
执行早期TCP协议的操作:发送一条消息(在您的情况下为JSON对象)并关闭连接。客户端检测到它并重新打开以获取下一个对象。
执行chunked-mode HTTP的操作:首先发送JSON对象中的字节数,换行符(HTTP中的CRLF)和JSON对象。客户端只需计算字节数就可以知道下一个字节何时成为下一个对象。
答案 1 :(得分:5)
当您想要提供浏览器客户端时,最接近原始TCP的是WebSockets。
WebSockets有足够的动力,浏览器供应商将提高支持(Chrome 14和Firefox 7/8支持最新的协议草案),并且广泛的客户端和服务器框架将支持它。
已经有几个开源客户端库,包括Autobahn WebSocket。
如果你想为自己烘焙一些东西(在原始TCP之上),我会为你的JSON消息推荐一种长度为前缀的格式,即Netstrings
免责声明:我是高速公路的作者并为Tavendo工作。
答案 2 :(得分:1)
我已经编纂了我和其他一些开发人员正在做的事情:
http://en.wikipedia.org/wiki/Line_Delimited_JSON
它具有与netcat / telnet兼容的优点。
另请参阅:http://ndjson.org/
答案 3 :(得分:1)
您可以使用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');
};
答案 4 :(得分:0)
消息的四个字节的第一个字节可以是32位整数,指示消息的大小(以字节为单位)。然后,接收者应遵循以下步骤:
C#中的发件人代码:
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);
}