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.

DomingoSL
  • 14,920
  • 24
  • 99
  • 173

1 Answers1

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));
Community
  • 1
  • 1
zangw
  • 43,869
  • 19
  • 177
  • 214