Choice of transports for JSON over TCP

Viewed 24293

I'm writing a simple streaming JSON service. It consists of JSON messages, sent intermittently, for a long period of time (weeks or months).

What is the best practise with regard to sending multiple JSON messages over a plain TCP socket?

Some alternatives I have looked at (and their downsides) are:

  1. newline separated JSON - downside: newlines within JSON require escaping, or prohibition
  2. websocket inspired 0x00 0xff framing - downside: it's now binary, not utf-8 anymore
  3. real websockets - downside: lack of (opensource) websocket client libraries
  4. http multipart http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html - downside: incomplete client support?
  5. no delimiters - downside: chunking requires JSON parsing (can't just count curlies because of curlies in strings)

Is there a good, or at least well-established way of doing this?

5 Answers

The first of four bytes of the message can be an 32-bit integer indicating size (in bytes) of the message. Then the receiver should follow these steps:

  1. Read the first four bytes of data and figure out the exact amount of bytes you need to read the whole message.
  2. Read the rest of the message and deserialize it as a JSON

Sender code in 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);
    }
Related