0

I've this Ruby server that uses a Unix Socket:

require 'socket'
require 'json'

server = UNIXServer.new('/tmp/ciccio.sock')
loop do
  sock = server.accept
  loop do
    begin
      data = sock.recv(1024)
      break if data.empty?
      # calculate a response
      response = {supermega: "very long json" * 10000}
      sock.write(response.to_json)
      sock.flush
    rescue Errno::EPIPE, Errno::ENOTCONN
      break
    end
  end
end

And I've this client in JavaScript that uses node.js net api:

Net = require('net');

var client = Net.connect({ path: '/tmp/ciccio.sock' }, () => {
    console.log('write data');
    client.write('hello world!');
});

client.on('data', (data) => {
    console.log(data.toString());
    var json = JSON.parse(data);
    // do something with json
});

client.on('end', () => {
    console.log('end');
});

client.on('error', (error) => {
    console.log(error.toString());
});

The problem is that if the data is big (over about 8193 characters) JSON.parse fail because data is chunked. How can I get the whole json as string and then parse it?

1 Answer 1

0

You should only parse the JSON when you have received all of the text. Try this in the client.

Net = require('net');

var client = Net.connect({ path: '/tmp/ciccio.sock' }, () => {
    console.log('write data');
    client.write('hello world!');
});

// this will contain the whole JSON String
var totalString = '';

client.on('data', (data) => {
    // progressively add the chunks to totalString
    var chunk = data.toString();
    console.log(chunk);
    totalString += chunk;
});

client.on('end', () => {
    // now you may parse the JSON
    var json = JSON.parse(totalString);
    totalString = ''; // release totalString to the garbage collector
    // now do something with json
    console.log('end');
});

client.on('error', (error) => {
    console.log(error.toString());
});

Note this could be done much more efficiently if you had some way of predicting the size of the data. String appending with += is very inefficient.

Sign up to request clarification or add additional context in comments.

4 Comments

The end event is never emitted in my example... I'm using net api (nodejs.org/docs/latest/api/net.html#net_event_end), not http api (nodejs.org/docs/latest/api/…)
@Pioz Now looking at your Ruby server, you never call sock.close. Have you tried doing that?
I don't want close my socket, I want to keep it opened... I don't want make a connection for every message.
@Pioz Ok so the thing you are calling sock is not a socket. It's a temporary connection on that socket. There will be no problem with closing it. Your AF_UNIX socket is held in the variable you have named server.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.