HenningM / express-ws

WebSocket endpoints for express applications
BSD 2-Clause "Simplified" License
877 stars 142 forks source link

getWss().clients returns object #109

Closed gultyayev closed 5 years ago

gultyayev commented 5 years ago

I wanted to look at all the clients at the moment on my WebSocket, but instead of some adequate array I've received some object which even cannot fit in terminal.

Here is my code

const express = require('express'),
    chalk = require('chalk'),
    app = express(),
    port = 3000,
    expressWs = require('express-ws')(app),
    path = require('path'),
    log = console.log,
    fs = require('fs'),
    util = require('util');

app.get('/', (req, res) => res.sendFile(path.join(__dirname, './index.html')));

expressWs.getWss().on('connection', _ => {
    log(chalk.bgGreen('WebSocket connection established'));
    fs.writeFile('./logs.txt', util.inspect(expressWs.getWss().clients), err => {
        if (err) return console.error(err);

        log(chalk.bgGreen('Saved!'));
    });
});

app.ws('/ws', (ws, req) => {
    ws.on('message', msg => {
        log(chalk.yellow('WS retrieved msg: ') + msg);

        ws.send('echo ' + msg);
    });
});

app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('500\n Internal server error')
})

app.listen(port, () => console.log(`Listening on port ${port}`));

Here is what I've got instead of my "clients"

Set {
  WebSocket {
    _events:
     [Object: null prototype] { close: [Function], message: [Function] },
    _eventsCount: 2,
    _maxListeners: undefined,
    readyState: 1,
    protocol: '',
    _binaryType: 'nodebuffer',
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: '',
    _closeTimer: null,
    _closeCode: 1006,
    _extensions: {},
    _isServer: true,
    _receiver:
     Receiver {
       _writableState:
        WritableState {
          objectMode: false,
          highWaterMark: 16384,
          finalCalled: false,
          needDrain: false,
          ending: false,
          ended: false,
          finished: false,
          destroyed: false,
          decodeStrings: true,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: true,
          bufferProcessing: false,
          onwrite: [Function: bound onwrite],
          writecb: null,
          writelen: 0,
          bufferedRequest: null,
          lastBufferedRequest: null,
          pendingcb: 0,
          prefinished: false,
          errorEmitted: false,
          emitClose: true,
          autoDestroy: false,
          bufferedRequestCount: 0,
          corkedRequestsFree:
           { next: null,
             entry: null,
             finish: [Function: bound onCorkedFinish] } },
       writable: true,
       _events:
        [Object: null prototype] {
          conclude: [Function: receiverOnConclude],
          drain: [Function: receiverOnDrain],
          error: [Function: receiverOnError],
          message: [Function: receiverOnMessage],
          ping: [Function: receiverOnPing],
          pong: [Function: receiverOnPong] },
       _eventsCount: 6,
       _maxListeners: undefined,
       _binaryType: 'nodebuffer',
       _extensions: {},
       _maxPayload: 104857600,
       _bufferedBytes: 0,
       _buffers: [],
       _compressed: false,
       _payloadLength: 0,
       _mask: undefined,
       _fragmented: 0,
       _masked: false,
       _fin: false,
       _opcode: 0,
       _totalPayloadLength: 0,
       _messageLength: 0,
       _fragments: [],
       _state: 0,
       _loop: false,
       [Symbol(websocket)]: [Circular] },
    _sender:
     Sender {
       _extensions: {},
       _socket:
        Socket {
          connecting: false,
          _hadError: false,
          _handle:
           TCP {
             reading: true,
             onread: [Function: onStreamRead],
             onconnection: null,
             _consumed: true,
             [Symbol(owner)]: [Circular] },
          _parent: null,
          _host: null,
          _readableState:
           ReadableState {
             objectMode: false,
             highWaterMark: 16384,
             buffer: BufferList { head: null, tail: null, length: 0 },
             length: 0,
             pipes: null,
             pipesCount: 0,
             flowing: true,
             ended: false,
             endEmitted: false,
             reading: true,
             sync: false,
             needReadable: true,
             emittedReadable: false,
             readableListening: false,
             resumeScheduled: true,
             emitClose: false,
             autoDestroy: false,
             destroyed: false,
             defaultEncoding: 'utf8',
             awaitDrain: 0,
             readingMore: false,
             decoder: null,
             encoding: null },
          readable: true,
          _events:
           [Object: null prototype] {
             end: [ [Function: onReadableStreamEnd], [Function: socketOnEnd] ],
             timeout: [Function: socketOnTimeout],
             close: [Function: socketOnClose],
             data: [Function: socketOnData],
             error: [Function: socketOnError] },
          _eventsCount: 5,
          _maxListeners: undefined,
          _writableState:
           WritableState {
             objectMode: false,
             highWaterMark: 16384,
             finalCalled: false,
             needDrain: false,
             ending: false,
             ended: false,
             finished: false,
             destroyed: false,
             decodeStrings: false,
             defaultEncoding: 'utf8',
             length: 0,
             writing: false,
             corked: 0,
             sync: false,
             bufferProcessing: false,
             onwrite: [Function: bound onwrite],
             writecb: null,
             writelen: 0,
             bufferedRequest: null,
             lastBufferedRequest: null,
             pendingcb: 1,
             prefinished: false,
             errorEmitted: false,
             emitClose: false,
             autoDestroy: false,
             bufferedRequestCount: 0,
             corkedRequestsFree:
              { next: null,
                entry: null,
                finish: [Function: bound onCorkedFinish] } },
          writable: true,
          allowHalfOpen: true,
          _sockname: null,
          _pendingData: null,
          _pendingEncoding: '',
          server:
           Server {
             _events:
              [Object: null prototype] {
                request:
                 { [EventEmitter: app]
                   _events: [Object: null prototype] { mount: [Function: onmount] },
                   _eventsCount: 1,
                   _maxListeners: undefined,
                   setMaxListeners: [Function: setMaxListeners],
                   getMaxListeners: [Function: getMaxListeners],
                   emit: [Function: emit],
                   addListener: [Function: addListener],
                   on: [Function: addListener],
                   prependListener: [Function: prependListener],
                   once: [Function: once],
                   prependOnceListener: [Function: prependOnceListener],
                   removeListener: [Function: removeListener],
                   off: [Function: removeListener],
                   removeAllListeners: [Function: removeAllListeners],
                   listeners: [Function: listeners],
                   rawListeners: [Function: rawListeners],
                   listenerCount: [Function: listenerCount],
                   eventNames: [Function: eventNames],
                   init: [Function: init],
                   defaultConfiguration: [Function: defaultConfiguration],
                   lazyrouter: [Function: lazyrouter],
                   handle: [Function: handle],
                   use: [Function: use],
                   route: [Function: route],
                   engine: [Function: engine],
                   param: [Function: param],
                   set: [Function: set],
                   path: [Function: path],
                   enabled: [Function: enabled],
                   disabled: [Function: disabled],
                   enable: [Function: enable],
                   disable: [Function: disable],
                   acl: [Function],
                   bind: [Function],
                   checkout: [Function],
                   connect: [Function],
                   copy: [Function],
                   delete: [Function],
                   get: [Function],
                   head: [Function],
                   link: [Function],
                   lock: [Function],
                   'm-search': [Function],
                   merge: [Function],
                   mkactivity: [Function],
                   mkcalendar: [Function],
                   mkcol: [Function],
                   move: [Function],
                   notify: [Function],
                   options: [Function],
                   patch: [Function],
                   post: [Function],
                   propfind: [Function],
                   proppatch: [Function],
                   purge: [Function],
                   put: [Function],
                   rebind: [Function],
                   report: [Function],
                   search: [Function],
                   source: [Function],
                   subscribe: [Function],
                   trace: [Function],
                   unbind: [Function],
                   unlink: [Function],
                   unlock: [Function],
                   unsubscribe: [Function],
                   all: [Function: all],
                   del: [Function],
                   render: [Function: render],
                   listen: [Function: serverListen],
                   request: IncomingMessage { app: [Circular] },
                   response: ServerResponse { app: [Circular] },
                   cache: {},
                   engines: {},
                   settings:
                    { 'x-powered-by': true,
                      etag: 'weak',
                      'etag fn': [Function: generateETag],
                      env: 'development',
                      'query parser': 'extended',
                      'query parser fn': [Function: parseExtendedQueryString],
                      'subdomain offset': 2,
                      'trust proxy': false,
                      'trust proxy fn': [Function: trustNone],
                      view: [Function: View],
                      views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                      'jsonp callback name': 'callback' },
                   locals:
                    [Object: null prototype] {
                      settings:
                       { 'x-powered-by': true,
                         etag: 'weak',
                         'etag fn': [Function: generateETag],
                         env: 'development',
                         'query parser': 'extended',
                         'query parser fn': [Function: parseExtendedQueryString],
                         'subdomain offset': 2,
                         'trust proxy': false,
                         'trust proxy fn': [Function: trustNone],
                         view: [Function: View],
                         views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                         'jsonp callback name': 'callback' } },
                   mountpath: '/',
                   ws: [Function: addWsRoute],
                   _router:
                    { [Function: router]
                      params: {},
                      _params: [],
                      caseSensitive: false,
                      mergeParams: undefined,
                      strict: false,
                      stack:
                       [ Layer {
                           handle: [Function: query],
                           name: 'query',
                           params: {},
                           path: '',
                           keys: [],
                           regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                           route: undefined },
                         Layer {
                           handle: [Function: expressInit],
                           name: 'expressInit',
                           params: {},
                           path: '',
                           keys: [],
                           regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                           route: undefined },
                         Layer {
                           handle: [Function: bound dispatch],
                           name: 'bound dispatch',
                           params: undefined,
                           path: undefined,
                           keys: [],
                           regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                           route:
                            Route {
                              path: '/',
                              stack:
                               [ Layer {
                                   handle: [Function],
                                   name: '<anonymous>',
                                   params: undefined,
                                   path: undefined,
                                   keys: [],
                                   regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                   method: 'get' } ],
                              methods: { get: true } } },
                         Layer {
                           handle: [Function: bound dispatch],
                           name: 'bound dispatch',
                           params: {},
                           path: '/ws/.websocket',
                           keys: [],
                           regexp:
                            { /^\/ws\/\.websocket\/?$/i fast_star: false, fast_slash: false },
                           route:
                            Route {
                              path: '/ws/.websocket',
                              stack:
                               [ Layer {
                                   handle: [Function],
                                   name: '<anonymous>',
                                   params: undefined,
                                   path: undefined,
                                   keys: [],
                                   regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                   method: 'get' } ],
                              methods: { get: true } } },
                         Layer {
                           handle: [Function],
                           name: '<anonymous>',
                           params: undefined,
                           path: undefined,
                           keys: [],
                           regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                           route: undefined } ] } },
                connection: [Function: connectionListener],
                listening: [Function: bound emit],
                error: [Function: bound emit],
                upgrade: [Function: upgrade] },
             _eventsCount: 5,
             _maxListeners: undefined,
             _connections: 2,
             _handle:
              TCP {
                reading: false,
                onread: null,
                onconnection: [Function: onconnection],
                [Symbol(owner)]: [Circular] },
             _usingWorkers: false,
             _workers: [],
             _unref: false,
             allowHalfOpen: true,
             pauseOnConnect: false,
             httpAllowHalfOpen: false,
             timeout: 120000,
             keepAliveTimeout: 5000,
             _pendingResponseData: 0,
             maxHeadersCount: null,
             headersTimeout: 40000,
             _connectionKey: '6::::3000',
             [Symbol(IncomingMessage)]: [Function: IncomingMessage],
             [Symbol(ServerResponse)]: [Function: ServerResponse],
             [Symbol(asyncId)]: 5 },
          _server:
           Server {
             _events:
              [Object: null prototype] {
                request:
                 { [EventEmitter: app]
                   _events: [Object: null prototype] { mount: [Function: onmount] },
                   _eventsCount: 1,
                   _maxListeners: undefined,
                   setMaxListeners: [Function: setMaxListeners],
                   getMaxListeners: [Function: getMaxListeners],
                   emit: [Function: emit],
                   addListener: [Function: addListener],
                   on: [Function: addListener],
                   prependListener: [Function: prependListener],
                   once: [Function: once],
                   prependOnceListener: [Function: prependOnceListener],
                   removeListener: [Function: removeListener],
                   off: [Function: removeListener],
                   removeAllListeners: [Function: removeAllListeners],
                   listeners: [Function: listeners],
                   rawListeners: [Function: rawListeners],
                   listenerCount: [Function: listenerCount],
                   eventNames: [Function: eventNames],
                   init: [Function: init],
                   defaultConfiguration: [Function: defaultConfiguration],
                   lazyrouter: [Function: lazyrouter],
                   handle: [Function: handle],
                   use: [Function: use],
                   route: [Function: route],
                   engine: [Function: engine],
                   param: [Function: param],
                   set: [Function: set],
                   path: [Function: path],
                   enabled: [Function: enabled],
                   disabled: [Function: disabled],
                   enable: [Function: enable],
                   disable: [Function: disable],
                   acl: [Function],
                   bind: [Function],
                   checkout: [Function],
                   connect: [Function],
                   copy: [Function],
                   delete: [Function],
                   get: [Function],
                   head: [Function],
                   link: [Function],
                   lock: [Function],
                   'm-search': [Function],
                   merge: [Function],
                   mkactivity: [Function],
                   mkcalendar: [Function],
                   mkcol: [Function],
                   move: [Function],
                   notify: [Function],
                   options: [Function],
                   patch: [Function],
                   post: [Function],
                   propfind: [Function],
                   proppatch: [Function],
                   purge: [Function],
                   put: [Function],
                   rebind: [Function],
                   report: [Function],
                   search: [Function],
                   source: [Function],
                   subscribe: [Function],
                   trace: [Function],
                   unbind: [Function],
                   unlink: [Function],
                   unlock: [Function],
                   unsubscribe: [Function],
                   all: [Function: all],
                   del: [Function],
                   render: [Function: render],
                   listen: [Function: serverListen],
                   request: IncomingMessage { app: [Circular] },
                   response: ServerResponse { app: [Circular] },
                   cache: {},
                   engines: {},
                   settings:
                    { 'x-powered-by': true,
                      etag: 'weak',
                      'etag fn': [Function: generateETag],
                      env: 'development',
                      'query parser': 'extended',
                      'query parser fn': [Function: parseExtendedQueryString],
                      'subdomain offset': 2,
                      'trust proxy': false,
                      'trust proxy fn': [Function: trustNone],
                      view: [Function: View],
                      views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                      'jsonp callback name': 'callback' },
                   locals:
                    [Object: null prototype] {
                      settings:
                       { 'x-powered-by': true,
                         etag: 'weak',
                         'etag fn': [Function: generateETag],
                         env: 'development',
                         'query parser': 'extended',
                         'query parser fn': [Function: parseExtendedQueryString],
                         'subdomain offset': 2,
                         'trust proxy': false,
                         'trust proxy fn': [Function: trustNone],
                         view: [Function: View],
                         views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                         'jsonp callback name': 'callback' } },
                   mountpath: '/',
                   ws: [Function: addWsRoute],
                   _router:
                    { [Function: router]
                      params: {},
                      _params: [],
                      caseSensitive: false,
                      mergeParams: undefined,
                      strict: false,
                      stack:
                       [ Layer {
                           handle: [Function: query],
                           name: 'query',
                           params: {},
                           path: '',
                           keys: [],
                           regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                           route: undefined },
                         Layer {
                           handle: [Function: expressInit],
                           name: 'expressInit',
                           params: {},
                           path: '',
                           keys: [],
                           regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                           route: undefined },
                         Layer {
                           handle: [Function: bound dispatch],
                           name: 'bound dispatch',
                           params: undefined,
                           path: undefined,
                           keys: [],
                           regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                           route:
                            Route {
                              path: '/',
                              stack:
                               [ Layer {
                                   handle: [Function],
                                   name: '<anonymous>',
                                   params: undefined,
                                   path: undefined,
                                   keys: [],
                                   regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                   method: 'get' } ],
                              methods: { get: true } } },
                         Layer {
                           handle: [Function: bound dispatch],
                           name: 'bound dispatch',
                           params: {},
                           path: '/ws/.websocket',
                           keys: [],
                           regexp:
                            { /^\/ws\/\.websocket\/?$/i fast_star: false, fast_slash: false },
                           route:
                            Route {
                              path: '/ws/.websocket',
                              stack:
                               [ Layer {
                                   handle: [Function],
                                   name: '<anonymous>',
                                   params: undefined,
                                   path: undefined,
                                   keys: [],
                                   regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                   method: 'get' } ],
                              methods: { get: true } } },
                         Layer {
                           handle: [Function],
                           name: '<anonymous>',
                           params: undefined,
                           path: undefined,
                           keys: [],
                           regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                           route: undefined } ] } },
                connection: [Function: connectionListener],
                listening: [Function: bound emit],
                error: [Function: bound emit],
                upgrade: [Function: upgrade] },
             _eventsCount: 5,
             _maxListeners: undefined,
             _connections: 2,
             _handle:
              TCP {
                reading: false,
                onread: null,
                onconnection: [Function: onconnection],
                [Symbol(owner)]: [Circular] },
             _usingWorkers: false,
             _workers: [],
             _unref: false,
             allowHalfOpen: true,
             pauseOnConnect: false,
             httpAllowHalfOpen: false,
             timeout: 120000,
             keepAliveTimeout: 5000,
             _pendingResponseData: 0,
             maxHeadersCount: null,
             headersTimeout: 40000,
             _connectionKey: '6::::3000',
             [Symbol(IncomingMessage)]: [Function: IncomingMessage],
             [Symbol(ServerResponse)]: [Function: ServerResponse],
             [Symbol(asyncId)]: 5 },
          timeout: 0,
          parser: null,
          on: [Function],
          _paused: false,
          [Symbol(asyncId)]: 32,
          [Symbol(lastWriteQueueSize)]: 0,
          [Symbol(timeout)]:
           Timeout {
             _idleTimeout: -1,
             _idlePrev: null,
             _idleNext: null,
             _idleStart: 2300,
             _onTimeout: null,
             _timerArgs: undefined,
             _repeat: null,
             _destroyed: false,
             [Symbol(refed)]: null,
             [Symbol(asyncId)]: 33,
             [Symbol(triggerId)]: 32 },
          [Symbol(kBytesRead)]: 0,
          [Symbol(kBytesWritten)]: 0,
          [Symbol(websocket)]: [Circular] },
       _firstFragment: true,
       _compress: false,
       _bufferedBytes: 0,
       _deflating: false,
       _queue: [] },
    _socket:
     Socket {
       connecting: false,
       _hadError: false,
       _handle:
        TCP {
          reading: true,
          onread: [Function: onStreamRead],
          onconnection: null,
          _consumed: true,
          [Symbol(owner)]: [Circular] },
       _parent: null,
       _host: null,
       _readableState:
        ReadableState {
          objectMode: false,
          highWaterMark: 16384,
          buffer: BufferList { head: null, tail: null, length: 0 },
          length: 0,
          pipes: null,
          pipesCount: 0,
          flowing: true,
          ended: false,
          endEmitted: false,
          reading: true,
          sync: false,
          needReadable: true,
          emittedReadable: false,
          readableListening: false,
          resumeScheduled: true,
          emitClose: false,
          autoDestroy: false,
          destroyed: false,
          defaultEncoding: 'utf8',
          awaitDrain: 0,
          readingMore: false,
          decoder: null,
          encoding: null },
       readable: true,
       _events:
        [Object: null prototype] {
          end: [ [Function: onReadableStreamEnd], [Function: socketOnEnd] ],
          timeout: [Function: socketOnTimeout],
          close: [Function: socketOnClose],
          data: [Function: socketOnData],
          error: [Function: socketOnError] },
       _eventsCount: 5,
       _maxListeners: undefined,
       _writableState:
        WritableState {
          objectMode: false,
          highWaterMark: 16384,
          finalCalled: false,
          needDrain: false,
          ending: false,
          ended: false,
          finished: false,
          destroyed: false,
          decodeStrings: false,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: false,
          bufferProcessing: false,
          onwrite: [Function: bound onwrite],
          writecb: null,
          writelen: 0,
          bufferedRequest: null,
          lastBufferedRequest: null,
          pendingcb: 1,
          prefinished: false,
          errorEmitted: false,
          emitClose: false,
          autoDestroy: false,
          bufferedRequestCount: 0,
          corkedRequestsFree:
           { next: null,
             entry: null,
             finish: [Function: bound onCorkedFinish] } },
       writable: true,
       allowHalfOpen: true,
       _sockname: null,
       _pendingData: null,
       _pendingEncoding: '',
       server:
        Server {
          _events:
           [Object: null prototype] {
             request:
              { [EventEmitter: app]
                _events: [Object: null prototype] { mount: [Function: onmount] },
                _eventsCount: 1,
                _maxListeners: undefined,
                setMaxListeners: [Function: setMaxListeners],
                getMaxListeners: [Function: getMaxListeners],
                emit: [Function: emit],
                addListener: [Function: addListener],
                on: [Function: addListener],
                prependListener: [Function: prependListener],
                once: [Function: once],
                prependOnceListener: [Function: prependOnceListener],
                removeListener: [Function: removeListener],
                off: [Function: removeListener],
                removeAllListeners: [Function: removeAllListeners],
                listeners: [Function: listeners],
                rawListeners: [Function: rawListeners],
                listenerCount: [Function: listenerCount],
                eventNames: [Function: eventNames],
                init: [Function: init],
                defaultConfiguration: [Function: defaultConfiguration],
                lazyrouter: [Function: lazyrouter],
                handle: [Function: handle],
                use: [Function: use],
                route: [Function: route],
                engine: [Function: engine],
                param: [Function: param],
                set: [Function: set],
                path: [Function: path],
                enabled: [Function: enabled],
                disabled: [Function: disabled],
                enable: [Function: enable],
                disable: [Function: disable],
                acl: [Function],
                bind: [Function],
                checkout: [Function],
                connect: [Function],
                copy: [Function],
                delete: [Function],
                get: [Function],
                head: [Function],
                link: [Function],
                lock: [Function],
                'm-search': [Function],
                merge: [Function],
                mkactivity: [Function],
                mkcalendar: [Function],
                mkcol: [Function],
                move: [Function],
                notify: [Function],
                options: [Function],
                patch: [Function],
                post: [Function],
                propfind: [Function],
                proppatch: [Function],
                purge: [Function],
                put: [Function],
                rebind: [Function],
                report: [Function],
                search: [Function],
                source: [Function],
                subscribe: [Function],
                trace: [Function],
                unbind: [Function],
                unlink: [Function],
                unlock: [Function],
                unsubscribe: [Function],
                all: [Function: all],
                del: [Function],
                render: [Function: render],
                listen: [Function: serverListen],
                request: IncomingMessage { app: [Circular] },
                response: ServerResponse { app: [Circular] },
                cache: {},
                engines: {},
                settings:
                 { 'x-powered-by': true,
                   etag: 'weak',
                   'etag fn': [Function: generateETag],
                   env: 'development',
                   'query parser': 'extended',
                   'query parser fn': [Function: parseExtendedQueryString],
                   'subdomain offset': 2,
                   'trust proxy': false,
                   'trust proxy fn': [Function: trustNone],
                   view: [Function: View],
                   views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                   'jsonp callback name': 'callback' },
                locals:
                 [Object: null prototype] {
                   settings:
                    { 'x-powered-by': true,
                      etag: 'weak',
                      'etag fn': [Function: generateETag],
                      env: 'development',
                      'query parser': 'extended',
                      'query parser fn': [Function: parseExtendedQueryString],
                      'subdomain offset': 2,
                      'trust proxy': false,
                      'trust proxy fn': [Function: trustNone],
                      view: [Function: View],
                      views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                      'jsonp callback name': 'callback' } },
                mountpath: '/',
                ws: [Function: addWsRoute],
                _router:
                 { [Function: router]
                   params: {},
                   _params: [],
                   caseSensitive: false,
                   mergeParams: undefined,
                   strict: false,
                   stack:
                    [ Layer {
                        handle: [Function: query],
                        name: 'query',
                        params: {},
                        path: '',
                        keys: [],
                        regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                        route: undefined },
                      Layer {
                        handle: [Function: expressInit],
                        name: 'expressInit',
                        params: {},
                        path: '',
                        keys: [],
                        regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                        route: undefined },
                      Layer {
                        handle: [Function: bound dispatch],
                        name: 'bound dispatch',
                        params: undefined,
                        path: undefined,
                        keys: [],
                        regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                        route:
                         Route {
                           path: '/',
                           stack:
                            [ Layer {
                                handle: [Function],
                                name: '<anonymous>',
                                params: undefined,
                                path: undefined,
                                keys: [],
                                regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                method: 'get' } ],
                           methods: { get: true } } },
                      Layer {
                        handle: [Function: bound dispatch],
                        name: 'bound dispatch',
                        params: {},
                        path: '/ws/.websocket',
                        keys: [],
                        regexp:
                         { /^\/ws\/\.websocket\/?$/i fast_star: false, fast_slash: false },
                        route:
                         Route {
                           path: '/ws/.websocket',
                           stack:
                            [ Layer {
                                handle: [Function],
                                name: '<anonymous>',
                                params: undefined,
                                path: undefined,
                                keys: [],
                                regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                method: 'get' } ],
                           methods: { get: true } } },
                      Layer {
                        handle: [Function],
                        name: '<anonymous>',
                        params: undefined,
                        path: undefined,
                        keys: [],
                        regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                        route: undefined } ] } },
             connection: [Function: connectionListener],
             listening: [Function: bound emit],
             error: [Function: bound emit],
             upgrade: [Function: upgrade] },
          _eventsCount: 5,
          _maxListeners: undefined,
          _connections: 2,
          _handle:
           TCP {
             reading: false,
             onread: null,
             onconnection: [Function: onconnection],
             [Symbol(owner)]: [Circular] },
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 120000,
          keepAliveTimeout: 5000,
          _pendingResponseData: 0,
          maxHeadersCount: null,
          headersTimeout: 40000,
          _connectionKey: '6::::3000',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(asyncId)]: 5 },
       _server:
        Server {
          _events:
           [Object: null prototype] {
             request:
              { [EventEmitter: app]
                _events: [Object: null prototype] { mount: [Function: onmount] },
                _eventsCount: 1,
                _maxListeners: undefined,
                setMaxListeners: [Function: setMaxListeners],
                getMaxListeners: [Function: getMaxListeners],
                emit: [Function: emit],
                addListener: [Function: addListener],
                on: [Function: addListener],
                prependListener: [Function: prependListener],
                once: [Function: once],
                prependOnceListener: [Function: prependOnceListener],
                removeListener: [Function: removeListener],
                off: [Function: removeListener],
                removeAllListeners: [Function: removeAllListeners],
                listeners: [Function: listeners],
                rawListeners: [Function: rawListeners],
                listenerCount: [Function: listenerCount],
                eventNames: [Function: eventNames],
                init: [Function: init],
                defaultConfiguration: [Function: defaultConfiguration],
                lazyrouter: [Function: lazyrouter],
                handle: [Function: handle],
                use: [Function: use],
                route: [Function: route],
                engine: [Function: engine],
                param: [Function: param],
                set: [Function: set],
                path: [Function: path],
                enabled: [Function: enabled],
                disabled: [Function: disabled],
                enable: [Function: enable],
                disable: [Function: disable],
                acl: [Function],
                bind: [Function],
                checkout: [Function],
                connect: [Function],
                copy: [Function],
                delete: [Function],
                get: [Function],
                head: [Function],
                link: [Function],
                lock: [Function],
                'm-search': [Function],
                merge: [Function],
                mkactivity: [Function],
                mkcalendar: [Function],
                mkcol: [Function],
                move: [Function],
                notify: [Function],
                options: [Function],
                patch: [Function],
                post: [Function],
                propfind: [Function],
                proppatch: [Function],
                purge: [Function],
                put: [Function],
                rebind: [Function],
                report: [Function],
                search: [Function],
                source: [Function],
                subscribe: [Function],
                trace: [Function],
                unbind: [Function],
                unlink: [Function],
                unlock: [Function],
                unsubscribe: [Function],
                all: [Function: all],
                del: [Function],
                render: [Function: render],
                listen: [Function: serverListen],
                request: IncomingMessage { app: [Circular] },
                response: ServerResponse { app: [Circular] },
                cache: {},
                engines: {},
                settings:
                 { 'x-powered-by': true,
                   etag: 'weak',
                   'etag fn': [Function: generateETag],
                   env: 'development',
                   'query parser': 'extended',
                   'query parser fn': [Function: parseExtendedQueryString],
                   'subdomain offset': 2,
                   'trust proxy': false,
                   'trust proxy fn': [Function: trustNone],
                   view: [Function: View],
                   views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                   'jsonp callback name': 'callback' },
                locals:
                 [Object: null prototype] {
                   settings:
                    { 'x-powered-by': true,
                      etag: 'weak',
                      'etag fn': [Function: generateETag],
                      env: 'development',
                      'query parser': 'extended',
                      'query parser fn': [Function: parseExtendedQueryString],
                      'subdomain offset': 2,
                      'trust proxy': false,
                      'trust proxy fn': [Function: trustNone],
                      view: [Function: View],
                      views: '/Users/sergeygultyayev/Projects/nodejs-learn/views',
                      'jsonp callback name': 'callback' } },
                mountpath: '/',
                ws: [Function: addWsRoute],
                _router:
                 { [Function: router]
                   params: {},
                   _params: [],
                   caseSensitive: false,
                   mergeParams: undefined,
                   strict: false,
                   stack:
                    [ Layer {
                        handle: [Function: query],
                        name: 'query',
                        params: {},
                        path: '',
                        keys: [],
                        regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                        route: undefined },
                      Layer {
                        handle: [Function: expressInit],
                        name: 'expressInit',
                        params: {},
                        path: '',
                        keys: [],
                        regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                        route: undefined },
                      Layer {
                        handle: [Function: bound dispatch],
                        name: 'bound dispatch',
                        params: undefined,
                        path: undefined,
                        keys: [],
                        regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                        route:
                         Route {
                           path: '/',
                           stack:
                            [ Layer {
                                handle: [Function],
                                name: '<anonymous>',
                                params: undefined,
                                path: undefined,
                                keys: [],
                                regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                method: 'get' } ],
                           methods: { get: true } } },
                      Layer {
                        handle: [Function: bound dispatch],
                        name: 'bound dispatch',
                        params: {},
                        path: '/ws/.websocket',
                        keys: [],
                        regexp:
                         { /^\/ws\/\.websocket\/?$/i fast_star: false, fast_slash: false },
                        route:
                         Route {
                           path: '/ws/.websocket',
                           stack:
                            [ Layer {
                                handle: [Function],
                                name: '<anonymous>',
                                params: undefined,
                                path: undefined,
                                keys: [],
                                regexp: { /^\/?$/i fast_star: false, fast_slash: false },
                                method: 'get' } ],
                           methods: { get: true } } },
                      Layer {
                        handle: [Function],
                        name: '<anonymous>',
                        params: undefined,
                        path: undefined,
                        keys: [],
                        regexp: { /^\/?(?=\/|$)/i fast_star: false, fast_slash: true },
                        route: undefined } ] } },
             connection: [Function: connectionListener],
             listening: [Function: bound emit],
             error: [Function: bound emit],
             upgrade: [Function: upgrade] },
          _eventsCount: 5,
          _maxListeners: undefined,
          _connections: 2,
          _handle:
           TCP {
             reading: false,
             onread: null,
             onconnection: [Function: onconnection],
             [Symbol(owner)]: [Circular] },
          _usingWorkers: false,
          _workers: [],
          _unref: false,
          allowHalfOpen: true,
          pauseOnConnect: false,
          httpAllowHalfOpen: false,
          timeout: 120000,
          keepAliveTimeout: 5000,
          _pendingResponseData: 0,
          maxHeadersCount: null,
          headersTimeout: 40000,
          _connectionKey: '6::::3000',
          [Symbol(IncomingMessage)]: [Function: IncomingMessage],
          [Symbol(ServerResponse)]: [Function: ServerResponse],
          [Symbol(asyncId)]: 5 },
       timeout: 0,
       parser: null,
       on: [Function],
       _paused: false,
       [Symbol(asyncId)]: 32,
       [Symbol(lastWriteQueueSize)]: 0,
       [Symbol(timeout)]:
        Timeout {
          _idleTimeout: -1,
          _idlePrev: null,
          _idleNext: null,
          _idleStart: 2300,
          _onTimeout: null,
          _timerArgs: undefined,
          _repeat: null,
          _destroyed: false,
          [Symbol(refed)]: null,
          [Symbol(asyncId)]: 33,
          [Symbol(triggerId)]: 32 },
       [Symbol(kBytesRead)]: 0,
       [Symbol(kBytesWritten)]: 0,
       [Symbol(websocket)]: [Circular] } } }
BrendanFDMoore commented 5 years ago

Did you figure out how to iterate the clients and send a message? When I traverse the clients with forEach as seen in the docs, the individual client entries have no send property. Not sure where to look for the client spec.

Janaka-Steph commented 5 years ago

For anyone who end up here, the object is a Set.

let clientsSet = wsInstance.getWss().clients
let clientsValues = clientsSet.values() 
for(let i=0; i < clientsSet.size; i++) {
  console.log(clientsValues.next().value)
}
sdz123 commented 3 years ago

run wsInstance.getWss().clients ,you will get a set,not object, so you should do : for (let client of wsInstance.getWss().clients){ // handle your job code //like this: client.send('this is a global message') }