1

I'm saving a connection/socket object in my program as follows:

var clients = [];
net.createServer(function (socket) {
    clients.push(socket);
    //morecode...

Later on the code I use that array to broadcast a message:

function broadcast(message, sender) {
    clients.forEach(function (client) {
        client.write(message);
    });
}

So far very simple. Now, I want to save the socket variable in my mongodb server so I can access it from different instances of my server application. My first approach was to do something like:

var client = new Client({
    name: socket.remoteAddress + ":" + socket.remotePort,
    socket: JSON.stringify(socket)
});

client.save(function (err) {
    if (err)
        console.log(err);
}); 

But I got: TypeError: Converting circular structure to JSON A suggestion I got from a similar question here in SO is to use util.inspect, with that I can manage to save an string representation of the socket var:

console.log(socket)

Socket {
  _connecting: false,
  _hadError: false,
  _handle:
   TCP {
     _externalStream: {},
     fd: 14,
     reading: true,
     owner: [Circular],
     onread: [Function: onread],
     onconnection: null,
     writeQueueSize: 0 },
  _parent: null,
  _host: null,
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: [],
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: null,
     ended: false,
     endEmitted: false,
     reading: true,
     sync: false,
     needReadable: true,
     emittedReadable: false,
     readableListening: false,
     resumeScheduled: false,
     defaultEncoding: 'utf8',
     ranOut: false,
     awaitDrain: 0,
     readingMore: false,
     decoder: null,
     encoding: null },
  readable: true,
  domain: null,
  _events:
   { end: { [Function: g] listener: [Function: onend] },
     finish: [Function: onSocketFinish],
     _socketEnd: [Function: onSocketEnd] },
  _eventsCount: 3,
  _maxListeners: undefined,
  _writableState:
   WritableState {
     objectMode: false,
     highWaterMark: 16384,
     needDrain: false,
     ending: false,
     ended: false,
     finished: false,
     decodeStrings: false,
     defaultEncoding: 'utf8',
     length: 0,
     writing: false,
     corked: 0,
     sync: true,
     bufferProcessing: false,
     onwrite: [Function],
     writecb: null,
     writelen: 0,
     bufferedRequest: null,
     lastBufferedRequest: null,
     pendingcb: 0,
     prefinished: false,
     errorEmitted: false },
  writable: true,
  allowHalfOpen: false,
  destroyed: false,
  bytesRead: 0,
  _bytesDispatched: 0,
  _sockname: null,
  _pendingData: null,
  _pendingEncoding: '',
  server:
   Server {
     domain: null,
     _events: { connection: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     _connections: 1,
     _handle:
      TCP {
        _externalStream: {},
        fd: 12,
        reading: false,
        owner: [Circular],
        onread: null,
        onconnection: [Function: onconnection],
        writeQueueSize: 0 },
     _usingSlaves: false,
     _slaves: [],
     _unref: false,
     allowHalfOpen: false,
     pauseOnConnect: false,
     _connectionKey: '6::::5000' } }

console.log(util.inspect(socket))

{ socket: 'Socket {\n _connecting: false,\n _hadError: false,\n _handle: \n TCP {\n
_externalStream: {},\n fd: 14,\n reading: true,\n owner: [Circular],\n onread: [Function: onread],\n onconnection: null,\n writeQueueSize: 0 },\n _parent: null,\n _host: null,\n _readableState: \n ReadableState {\n objectMode: false,\n highWaterMark: 16384,\n buffer: [],\n length: 0,\n pipes: null,\n pipesCount: 0,\n flowing: null,\n ended: false,\n endEmitted: false,\n reading: true,\n sync: false,\n
needReadable: true,\n emittedReadable: false,\n
readableListening: false,\n resumeScheduled: false,\n
defaultEncoding: \'utf8\',\n ranOut: false,\n awaitDrain: 0,\n readingMore: false,\n decoder: null,\n encoding: null },\n readable: true,\n domain: null,\n _events: \n { end: { [Function: g] listener: [Function: onend] },\n finish: [Function: onSocketFinish],\n _socketEnd: [Function: onSocketEnd] },\n _eventsCount: 3,\n _maxListeners: undefined,\n _writableState: \n WritableState {\n objectMode: false,\n highWaterMark: 16384,\n needDrain: false,\n ending: false,\n ended: false,\n
finished: false,\n decodeStrings: false,\n defaultEncoding: \'utf8\',\n length: 0,\n writing: false,\n corked: 0,\n
sync: true,\n bufferProcessing: false,\n onwrite: [Function],\n writecb: null,\n writelen: 0,\n
bufferedRequest: null,\n lastBufferedRequest: null,\n
pendingcb: 0,\n prefinished: false,\n errorEmitted: false },\n writable: true,\n allowHalfOpen: false,\n destroyed: false,\n bytesRead: 0,\n _bytesDispatched: 0,\n _sockname: null,\n _pendingData: null,\n _pendingEncoding: \'\',\n server: \n Server {\n domain: null,\n _events: { connection: [Function] },\n
_eventsCount: 1,\n _maxListeners: undefined,\n _connections: 1,\n _handle: \n TCP {\n _externalStream: {},\n
fd: 12,\n reading: false,\n owner: [Circular],\n
onread: null,\n onconnection: [Function: onconnection],\n
writeQueueSize: 0 },\n _usingSlaves: false,\n _slaves: [],\n
_unref: false,\n allowHalfOpen: false,\n pauseOnConnect: false,\n _connectionKey: \'6::::5000\' },\n _peername: { address: \'::ffff:XXXXXXX\', family: \'IPv6\', port: 1145 },\n' }' }

In that form, I can save it to mongodb, but I have no idea how to reconvert it to a socket object nodejs can use.

2
  • I doubt it is possible. net.Socket uses TCP sockets, and you basically want 2 different processes use the same socket simultaneously. Commented Feb 13, 2016 at 23:09
  • did you find a solution? Commented Jan 4, 2018 at 6:46

1 Answer 1

0

Another work around to solve TypeError: Converting circular structure to JSON, to custom JSON.stringify as below

var cache = [];
var obj = JSON.stringify(sock, function(key, value) {
    if (typeof value === 'object' && value !== null) {
        if (cache.indexOf(value) !== -1) {
            // Circular reference found, discard key
            return;
        }
        // Store value in our collection
        cache.push(value);
    }
    return value;
});
cache = null; // Enable garbage collection

console.log(obj);

So it is easy to reconvert it to a socket object through JSON.parse

console.log(JSON.parse(obj));
Sign up to request clarification or add additional context in comments.

1 Comment

this does not work as the object you get back after parsing such an object is not a socket object anymore.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.