Git Product home page Git Product logo

socket.io-admin-ui's Introduction

Socket.IO Admin UI

dashboard screenshot

Table of contents

How to use

Server-side

First, install the @socket.io/admin-ui package:

npm i @socket.io/admin-ui

And then invoke the instrument method on your Socket.IO server:

const { createServer } = require("http");
const { Server } = require("socket.io");
const { instrument } = require("@socket.io/admin-ui");

const httpServer = createServer();

const io = new Server(httpServer, {
  cors: {
    origin: ["https://admin.socket.io"],
    credentials: true
  }
});

instrument(io, {
  auth: false
});

httpServer.listen(3000);

The module is compatible with:

  • Socket.IO v4 server
  • Socket.IO v3 server (>= 3.1.0), but without the operations on rooms (join, leave, disconnection)

Client-side

You can then head up to https://admin.socket.io, or host the files found in the ui/dist folder.

Important note: the website at https://admin.socket.io is totally static (hosted on Vercel), we do not (and will never) store any information about yourself or your browser (no tracking, no analytics, ...). That being said, hosting the files yourself is totally fine.

You should see the following modal:

login modal screenshot

Please enter the URL of your server (for example, http://localhost:3000 or https://example.com) and the credentials, if applicable (see the auth option below).

Available options

auth

Default value: -

This option is mandatory. You can either disable authentication (please use with caution):

instrument(io, {
  auth: false
});

Or use basic authentication:

instrument(io, {
  auth: {
    type: "basic",
    username: "admin",
    password: "$2b$10$heqvAkYMez.Va6Et2uXInOnkCT6/uQj1brkrbyG3LpopDklcq7ZOS" // "changeit" encrypted with bcrypt
  },
});

WARNING! Please note that the bcrypt package does not currently support hashes starting with the $2y$ prefix, which is used by some BCrypt implementations (for example https://bcrypt-generator.com/ or https://www.bcrypt.fr/). You can check the validity of the hash with:

$ node
> require("bcrypt").compareSync("<the password>", "<the hash>")
true

You can generate a valid hash with:

$ node
> require("bcrypt").hashSync("changeit", 10)
'$2b$10$LQUE...'

See also:

namespaceName

Default value: /admin

The name of the namespace which will be created to handle the administrative tasks.

instrument(io, {
  namespaceName: "/custom"
});

This namespace is a classic Socket.IO namespace, you can access it with:

const adminNamespace = io.of("/admin");

More information here.

readonly

Default value: false

Whether to put the admin UI in read-only mode (no join, leave or disconnect allowed).

instrument(io, {
  readonly: true
});

serverId

Default value: require("os").hostname()

The ID of the given server. If you have several Socket.IO servers on the same machine, please give them a distinct ID:

instrument(io, {
  serverId: `${require("os").hostname()}#${process.pid}`
});

store

Default value: new InMemoryStore()

The store is used to store the session IDs so the user do not have to retype the credentials upon reconnection.

If you use basic authentication in a multi-server setup, you should provide a custom store:

const { instrument, RedisStore } = require("@socket.io/admin-ui");

instrument(io, {
  store: new RedisStore(redisClient)
});

mode

Default value: development

In production mode, the server won't send all details about the socket instances and the rooms, thus reducing the memory footprint of the instrumentation.

instrument(io, {
  mode: "production"
});

The production mode can also be enabled with the NODE_ENV environment variable:

NODE_ENV=production node index.js

How it works

You can check the details of the implementation in the lib/index.ts file.

The instrument method simply:

  • creates a namespace and adds an authentication middleware if applicable
  • register listeners for the connection and disconnect event for each existing namespaces to track socket instances
  • register a timer which will periodically send stats from the server to the UI
  • register handlers for the join, leave and _disconnect commands sent from the UI

License

MIT

socket.io-admin-ui's People

Contributors

c1200 avatar darrachequesne avatar dharmarajx24 avatar frozeeen avatar hmu332233 avatar hsnlbnan avatar imithu avatar oldthreefeng avatar rayrny avatar xpecex avatar yuhhang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

socket.io-admin-ui's Issues

@socket.io/admin-ui is not compatible with @socket.io/redis-adapter

Node version: 16.15.1
npm:8.11.0
@socket.io/admin-ui :0.4.0
@socket.io/redis-adapter:7.2.0

Following code will produce error
`
const http = require('http');
const express = require('express');
const socketio = require('socket.io');

const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");
const { instrument } = require("@socket.io/admin-ui");
const app = express();
const server = http.createServer(app);
const io = socketio(server, {transports: ['websocket'],});

const pubClient = createClient({ url: redis://${REDIS_HOST}:${REDIS_PORT} });
const subClient = pubClient.duplicate();

io.adapter(createAdapter(pubClient, subClient));
`

Error given below

var/www/html/ludo-app-server/node_modules/@redis/client/dist/lib/client/index.js:407 return Promise.reject(new errors_1.ClientClosedError()); ^ ClientClosedError: The client is closed at Commander._RedisClient_sendCommand (/var/www/html/ludo-app-server/node_modules/@redis/client/dist/lib/client/index.js:407:31) at Commander.commandsExecutor (/var/www/html/ludo-app-server/node_modules/@redis/client/dist/lib/client/index.js:170:154) at Commander.BaseClass.<computed> [as publish] (/var/www/html/ludo-app-server/node_modules/@redis/client/dist/lib/commander.js:8:29) at RedisAdapter.broadcast (/var/www/html/ludo-app-server/node_modules/@socket.io/redis-adapter/dist/index.js:463:28) at BroadcastOperator.emit (/var/www/html/ludo-app-server/node_modules/socket.io/dist/broadcast-operator.js:125:26) at Namespace.emit (/var/www/html/ludo-app-server/node_modules/socket.io/dist/namespace.js:170:73) at emitStats (/var/www/html/ludo-app-server/node_modules/@socket.io/admin-ui/dist/index.js:92:24) at initStatsEmitter (/var/www/html/ludo-app-server/node_modules/@socket.io/admin-ui/dist/index.js:102:5) at instrument (/var/www/html/ludo-app-server/node_modules/@socket.io/admin-ui/dist/index.js:432:5)

package.json dependencies
"dependencies": { "@elastic/ecs-winston-format": "^1.3.1", "@socket.io/admin-ui": "^0.4.0", "@socket.io/redis-adapter": "^7.2.0", "aws-sdk": "^2.968.0", "axios": "^0.27.2", "bufferutil": "^4.0.6", "bull": "^4.8.4", "debug": "^4.2.0", "dotenv": "^16.0.1", "eiows": "^4.1.2", "express": "^4.17.1", "express-rate-limit": "^6.4.0", "fs": "^0.0.1-security", "got": "^12.1.0", "ioredis": "^5.0.4", "ip": "^1.1.5", "joi": "^17.3.0", "jsonwebtoken": "^8.5.1", "mongoose": "^6.4.1", "node-cron": "^3.0.1", "package-json": "^8.1.0", "rate-limiter-flexible": "^2.1.13", "redis": "^4.1.0", "shelljs": "^0.8.4", "socket.io": "^4.0.0", "socket.io-client": "^4.4.1", "template-file": "^6.0.1", "truncate-logs": "^1.0.4", "utf-8-validate": "^5.0.8", "uuid": "^8.3.2", "winston": "^3.6.0" }, "devDependencies": { "nodemon": "^2.0.18" }

Feature Request - Receive and emit messages from the UI

Hi

Currently the admin-ui let us gather useful information about connected sockets, rooms for a targeted server…

What do you envision as the next steps?

I think this would be very useful if it we could display all messages received in a room and also offer the possibility to emit messages to it. This way it would allow to gather even more clues about what's happening during a debug session and test various behaviors.

Thanks a lot for this tool

Support relative links in index.html

Hi

I am serving the ui files in my Express app via
app.use(express.static(path.resolve('public')));

in a subdirectory called socket.ui. With the index.html provided this doesn't work as the links to css, webpack etc. start with /

If you could change it to relative links, this should work.

Best,
Thomas

Socket.IO - All users leave the room when a single user leaves

I'm working on a multiplayer game using Socket.IO and React where users can join a room using a unique game pin. When a user leaves the room, I want to emit a 'userLeft' event to the remaining users in the room. However, when a single user leaves the room, all users are being removed from the room, and the 'userLeft' event is not being received by any user.

The issue occurs even though I'm not calling socket.leave() on the server-side. When I log the clients in the room before handling the 'leaveGame' event, all clients are still in the room. But when I enter the event handler for 'leaveGame' on the server-side, the room is empty.

Here's my server-side code:

function logClientsInRoom(roomName) {
    const clientsInRoom = Array.from(
      io.sockets.adapter.rooms.get(roomName) || []
    );
    console.log(`Clients in room ${roomName}:`, clientsInRoom);
  }

socket.on("joinGame", async (data) => {
      try {
        const { name, isCreator, gamePin } = data;
        socket.join(gamePin);
        console.log(`${name} joined room: `, gamePin);
        logClientsInRoom(gamePin);
        socket.emit("gameJoined", newData);
        socket.to(gamePin).emit("userJoined", newData);
      } catch (error) {
        console.log(error);
      }
    });

socket.on("leaveGame", async (data) => {
      try {
        const { gamePin, name } = data;
        console.log("userLeaving", data);
        socket.to(gamePin).emit("userLeft", name);
        logClientsInRoom(gamePin);
      } catch (error) {
        console.log(error);
      }
    });

When a user creates a room it displays :
Haz joined room: 825072 Clients in room 825072: [ 'UFr55p1UUTQWr6q_AAAG' ] Mol joined room: 825072 Clients in room 825072: [ 'UFr55p1UUTQWr6q_AAAG', 'n4SpYjvY-r8JzI8-AAAH' ]

However when my client-side calls "userLeaving", this is what logClientsInRoom logs: Clients in room 825072: []

Here's my client-side code:

const handleLeave = () => {
    const dataToSend = {
      name,
      gamePin: game.pin,
    };
    console.log("Emitting leaveGame event from client-side");
    socket.emit("leaveGame", dataToSend);
    navigation.navigate("Home");
  };

useEffect(() => {
    socket.on("gameCreated", (gameData) => {
      console.log(gameData);
      setRoomPin(gameData.pin);
      setGame(gameData);
      setLoading(false);
    });
    socket.on("userJoined", (updatedGame) => {
      console.log("userJoined", updatedGame);
      setGame(updatedGame);
    });
    socket.on("userLeft", (name) => {
      console.log(`${name} left the game`);
    });
  }, [socket]);

The userLeft listener isn't called because when the server side socket.to(gamePin).emit("userLeft", name); is called the room is already empty, so there is no one to listen to that event.

I want to understand why all users are being removed from the room when a single user leaves, and how to fix this issue so that the 'userLeft' event is received by the remaining users in the room.

Please let me know if you need any additional information or clarification.

Use Nuxt

use nuxt (vue based framework) instead of vue

Using Admin UI with Acknowledgements breaks with Could not encode error

Libraries used:
Socket IO
socket.io-admin-ui
socket.io-redis

When receiving an event with an acknowledgment callback, I'm seeing a 'Could not encode' error being thrown from within socket.io-redis.

It appears to be caused by the additional timestamp being added here:

  socket.onAny((...args) => {
      adminNamespace.emit("event_received", nsp.name, socket.id, args, new Date());
  });

This is then passed through the Socket IO Broadcast Adapter, and then to the Redis Adapter which serialises all the arguments. When it tries to serialise the callback function, it throws an error since the encode library used doesn't support functions.

Without Admin UI installed, this issue is avoided because the Broadcast Adapter correctly identifies the acknowledgement callback. It does this using this with the following code:
const withAck = typeof data[data.length - 1] === "function";

When Admin UI is installed and enabled, the line above doesn't detect the acknowledgement as it is no longer the last argument.

logout feature

add logout feature which will clear the browser local storage



Thank you

xhr poll error when connecting with deployed server

when i try to connect my server from localhost it works and connects with admin UI but when i deployed it on some shared hosting its working fine with the android and react js apps but not connecting with the ADMIN UI of socket it shows the xhr poll error when i want to connect

"Error: Could not encode" when set mode "development"

I notice I only have dashboard and servers menu
after login

I think this is because start my nodejs using "NODE_ENV=production node index.js" so I set mode code specifically in code

instrument(io, {
  auth: {
     ...
  },
  mode: "development"
});

But then server crash with error

Error: Could not encode
 at _encode (/home/express/node_modules/notepack.io/lib/encode.js:256:13)
 at _encode (/home/express/node_modules/notepack.io/lib/encode.js:162:19)
 at _encode (/home/express/node_modules/notepack.io/lib/encode.js:162:19)
 at _encode (/home/express/node_modules/notepack.io/lib/encode.js:246:17)
 at _encode (/home/express/node_modules/notepack.io/lib/encode.js:162:19)
 at Object.encode (/home/express/node_modules/notepack.io/lib/encode.js:261:41)
 at RedisAdapter.broadcast (/home/express/node_modules/socket.io-redis/dist/index.js:313:33)
 at BroadcastOperator.emit (/home/express/node_modules/socket.io/dist/broadcast-operator.js:109:22)
 at Namespace.emit (/home/express/node_modules/socket.io/dist/namespace.js:170:73)
 at Socket.<anonymous> (/home/express/node_modules/@socket.io/admin-ui/dist/index.js:284:36)

I searched this error and found someone else also hit this error

https://bestofvue.com/repo/socketio-socket-io-admin-ui-vuejs-web-sockets (at "7. Error serialising sockets with session stores")

How to use it with redis Adapter?

If we have multiple servers running on different ports and those attached with Redis Adapter, how can we show the combined view of all the servers at the same page in admin UI?

RedisClient library used for RedisStore

I am trying to use the RedisStore for sessionId storage and I am not seeing any entry in RedisDB for this. So, I want to know which RedisClient is being used to insert key in RedisDB.
I use "ioredis": "^5.2.5" in my nodejs application. The admin UI is working correctly. I was expecting an entry in Redis but not seeing one. So, I want to understand this a little better.

[documentation] Package not available on npm.

  • I was not able to find the package @socket.io/admin-ui or admin-ui under socket.io organization on npm.
  • If currently it is intended to install using source code, steps & instructions should be added to documentation.

Dashboard does not show all tabs and data

image

I googled and could not find any solution to my problem so please help me out.

I am using strapi v4 inside the index.js bootstrap function I defined my sockets. They are working with no problems.

I wanted to launch admin.socket.io to start implementing some more logic, but when connected to the admin dashboard I don't see much. only two tabs.

index.js file

"use strict";
module.exports = {
  /**
   * An asynchronous register function that runs before
   * your application is initialized.
   *
   * This gives you an opportunity to extend code.
   */
  register(/*{ strapi }*/) { },

  /**
   * An asynchronous bootstrap function that runs before
   * your application gets started.
   *
   * This gives you an opportunity to set up your data model,
   * run jobs, or perform some special logic.
   */
  bootstrap({ strapi }) {
    const io = require("socket.io")(strapi.server.httpServer, {
      cors: {
        origin: ["https://admin.socket.io"],
        credentials: true
      },
    });

    const { instrument } = require('@socket.io/admin-ui');

    io.on("connection", function (socket) {
      console.log(`Connected ${socket.id}`);
    });

    strapi.io = io;
    instrument(io, { auth: false });
  },
};

[Question] Why not Vue 3?

As the heading suggests, this is more of a question than an issue.

Why not use vue 3?
Is it because of Vuetify(since it doesnt have a vue 3 integration yet)?

admin ui completely breaks my application

when initializing the admin ui, my application is unable to do anything. it can't even do console.log() when a user connects. I am sure the user connects and even the admin ui says that a user has connected. Furthermore, all functions do not work, the app can't seem to broadcast or callback, but the ui does say that the event was received

Also I can't connect to any name spaces when I use the admin ui. I seriously have no idea why any of this happens

Feature Request: Add option to "uninstrument" from the io server

Is there a way to "uninstrument" the socket.io server instance to avoid any kind of performance overhead after one has disconnected from the admin dashboard?

If not, it would be nice if there was an uninstrument method exported from the package that would allow to unregister all the event handlers that the package is attaching to the io instance.

Cannot read property 'on' of undefined

I'am trying to get admin-ui to work, but I always get this error from the node_module, when inserting:

instrument(io, { auth: false, });

Any ideas to fix this?

[INFO] 17:33:57 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.1, typescript ver. 4.7.4) TypeError: Cannot read property 'on' of undefined at registerEngineListeners (/Volumes/Privat/Code/projects/socketio-server/node_modules/@socket.io/admin-ui/dist/index.js:366:15) at instrument (/Volumes/Privat/Code/projects/socketio-server/node_modules/@socket.io/admin-ui/dist/index.js:424:5) at Object.<anonymous> (/Volumes/Privat/Code/projects/socketio-server/src/index.ts:48:11) at Module._compile (internal/modules/cjs/loader.js:1085:14) at Module._compile (/Volumes/Privat/Code/projects/socketio-server/node_modules/source-map-support/source-map-support.js:568:25) at Module.m._compile (/private/var/folders/73/1v90d1r53836q4zfl33hpb400000gp/T/ts-node-dev-hook-5528744062605151.js:69:33) at Module._extensions..js (internal/modules/cjs/loader.js:1114:10) at require.extensions..jsx.require.extensions..js (/private/var/folders/73/1v90d1r53836q4zfl33hpb400000gp/T/ts-node-dev-hook-5528744062605151.js:114:20) at require.extensions.<computed> (/private/var/folders/73/1v90d1r53836q4zfl33hpb400000gp/T/ts-node-dev-hook-5528744062605151.js:71:20) at Object.nodeDevHook [as .ts] (/Volumes/Privat/Code/projects/socketio-server/node_modules/ts-node-dev/lib/hook.js:63:13) [ERROR] 17:33:57 TypeError: Cannot read property 'on' of undefined

Problem with redis-adapter

Hi. I faced with error. Try use nestjs, socket.io, redis-adapter, admin-ui.

     "socket.io": "4.4.1"
    "@nestjs/platform-socket.io": "^8.2.6",
    "@nestjs/websockets": "^8.2.6",
    "@socket.io/admin-ui": "^0.2.0",
    "@socket.io/redis-adapter": "^7.1.0",
export class RedisIoAdapter extends IoAdapter {
  constructor(
    private readonly redisClient: RedisClientType,
    private readonly appOrHttpServer: INestApplicationContext,
  ) {
    super(appOrHttpServer);
  }

  public createIOServer(port: number, options?: ServerOptions) {
    const pubClient = this.redisClient.duplicate();
    const subClient = this.redisClient.duplicate();
    const server = super.createIOServer(port, options);
    instrument(server, {
      auth: false,
      store: new RedisStore(this.redisClient.duplicate()),
      serverId: `${os.hostname()}#${process.pid}`,
    });
    server.adapter(createAdapter(pubClient, subClient));
    return server;
  }
}
/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/@node-redis/client/dist/lib/client/index.js:407
        return Promise.reject(new errors_1.ClientClosedError());
                              ^
Error: The client is closed
    at Commander._RedisClient_sendCommand (/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/@node-redis/client/dist/lib/client/index.js:407:31)
    at Commander.commandsExecutor (/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/@node-redis/client/dist/lib/client/index.js:166:154)
    at Commander.BaseClass.<computed> [as publish] (/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/@node-redis/client/dist/lib/commander.js:8:29)
    at RedisAdapter.broadcast (/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/@socket.io/redis-adapter/dist/index.js:406:28)
    at BroadcastOperator.emit (/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/socket.io/dist/broadcast-operator.js:109:22)
    at Namespace.emit (/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/socket.io/dist/namespace.js:170:73)
    at Timeout.emitStats [as _onTimeout] (/Users/aliaksandrnatashkin/WebstormProjects/cellnft-backend/node_modules/@socket.io/admin-ui/dist/index.js:75:24)
    at listOnTimeout (node:internal/timers:557:17)
    at processTimers (node:internal/timers:500:7)

if comment instrument everything work, if comment adapter work too

Host Admin UI dist on a subdirectory

Hi there,

I want to host the Admin UI dist on my own server due to some privacy policies, but I don't want to have a separate domain or subdomain for this repo. I want to define a new location in my Nginx configuration and host the original dist provided here on that particular location, let's say at /admin-ui.

But the problem is, my implementation fails to serve the JS and CSS resources when I try to access the Admin UI on my subdirectory route. I have tried setting the base tag in my dist/index.html file but it is also not working.

Is there any way I can clone this project directly on my server and then serve the static UI on a subdirectory route?

Login issue on multi-server setup (xhr post error, Session ID unknown)

Hi! I have a problem logging into the admin panel when I have multiple servers in a load-balancing group.

Му instrument configuration looks like:

instrument(io, {
  readonly: true,
  auth: false,
  store: new RedisStore(redisClient)}
})

My socket.io configuration:

{
    "allowEIO3": true,
    "transports": ["polling", "websocket"],
    "cors": {
        "origin": ["https://admin.socket.io"]
    }
}

When I try to connect to application with single server in load-balancing group everything works fine and I can see the connection metadata in Redis.

But when I try to connect to application with multiple servers I get error xhr post error

Request:

POST /socket.io/?EIO=4&transport=polling&t=NayhWmL&sid=jlBhx1IfS1dZEpWOAANq HTTP/2
Host: develop.myserver.app:3001
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: */*
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Content-type: text/plain;charset=UTF-8
Content-Length: 1
Origin: https://admin.socket.io
Connection: keep-alive
Referer: https://admin.socket.io/
TE: Trailers

Response:

HTTP/2 400 Bad Request
date: Wed, 05 May 2021 13:18:29 GMT
content-type: application/json
set-cookie: AWSALB=/3ZFJ1ljYdZVVpueuztmZeLiyAzPiZ+m9iRf0L8SZLZw2Y44fUk6E5IThvk0+5Z+FurdStn9oIWXtqtGWB5ibYLcEU6OlqOWcMC75zpmSks+cT1WNg7YVcEHe; Expires=Wed, 12 May 2021 13:18:29 GMT; Path=/
set-cookie: AWSALBCORS=/3ZFJ1ljYdZVVpueuztmZeLiyAzPiZ+m9iRf0L8SZw2Y44fUk6E5IThvk0+5Z+FurdStn9oIWXtqtGWB5ibYLcEU6OlqOWcMCh5W75zpmSks+cT1WNg7YVcEHe; Expires=Wed, 12 May 2021 13:18:29 GMT; Path=/; SameSite=None; Secure
access-control-allow-origin: https://admin.socket.io
vary: Origin
X-Firefox-Spdy: h2

Response body:

{"code":1,"message":"Session ID unknown"}

UI not showing running socket.io server and users

Hi

express: 4.17.2
socket.io: 4.4.1
@socket.io/admin-ui: 0.3.0

I have added the ui backend to my socket.io / Express backend like this

    instrument(this.socketServer, {
      auth: {
        type: "basic",
        username: "admin",
        password: "$2b$10$..."
      },
      readonly: true,
      namespaceName: "/socketui"
    });

After i booted my backend, i can login to the ui (it says "connected") but i always see 0 servers and 0 clients online.

My socket.io server requires that for every event a token (jwt) has to be sent with the token attribute, but i don't think this should block the admin ui from showing stuff.

I don't know what im doing wrong here

Best,
Thomas

Make socket manager path configurable on connection form

Hello,

Small feature request to make the socket path configurable on the connection form.

At the moment, 'path' option is not being used and so the socket connection path defaults to '/socket.io'. This makes the tool unusable for anyone not using the default path.

I have linked to the line of code where the socket is instantiated:

const socket = io(serverUrl, {

Thank you!

Switch to bcryptjs instead of bcrypt (or include node-gyp as depency)

Hi

package version: 0.4.0

In my project, i have included the admin ui via my package.json. Now i migrated to another development machine and my project fails to build. I noticed the following in my package-lock.json

    "node_modules/@socket.io/admin-ui": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/@socket.io/admin-ui/-/admin-ui-0.4.0.tgz",
       "integrity": "sha512-ZidOoJdlqtL0cP/fdD0KygoobJty/eVKGGtlPff/oZpyskEMvFXZbOhV1e4aQamRptO6l0/qG+TWCCXmXRtG5A==",
       "dependencies": {
          "@types/bcrypt": "~3.0.0",
          "bcrypt": "~5.0.1",
          "debug": "~4.3.1"
       },
       "peerDependencies": {
          "socket.io": ">=3.1.0"
       }
    },

Then i found this thread regarding bcrypt.js
dcodeIO/bcrypt.js#112

For my project to build, i had to globally install npm i -g node-gyp and then after removing everything in node_modules do an npm install

Maybe its best to include node-gyp in your depencies or switch to bcryptjs, which (according to the docs) is plain js instead of a native build and doesn't require node-gyp

Best,
Thomas

Kills the performance of Socket.io Server

My socket server can handle 10K connection easily.

But when i configured the admin ui ,with namespaceName as "/", socket server can handle max 1K connection and connections starts disconnecting.
instrument(io, { auth: false, namespaceName:'/ });

Have tested it multiple times.

But if i keep the namespaceName to 'admin' or 'someThingButNot/', it works fine.

instrument(io, { auth: false, namespaceName:'adminBro' });

cors error

I want to connect client web page for socketIO and admin-ui to socketIO server.
But the error appears.

When I use this code below, the client web disconnects with cors error.

const io = new Server(httpServer, {
cors: {
origin: "https://admin.socket.io",
},
});
instrument(io, {
auth: false,
});

Of course, I did like this, and "xhr poll error" happens on admin-ui.

const io = new Server(httpServer, {
cors: {
origin: "", // and I did ["https://admin.socket.io",""] instead of this
},
});
instrument(io, {
auth: false,
});

does admin-ui supports only local environment?

Page unresponsive on 10K Socket Connections

Page is not responsive when when large number of sockets are connected (~10K).

Have tested in 2 scenarios:

  1. Start SocketIO server,Open Admin UI Page, now add load 10K socket connections in realtime, 10K connections are instantly connected on the server but Admin UI Page couldn't keep up with the real count.It then became unresponsive as it is with flooded with realtime docket data.

  2. Start SocketIO server,add load 10K socket connections,now open Admin UI,it will take long to connect and then page became unresponsive.

Screenshot from 2021-07-07 00-05-10

Admin UI Not Showing All Servers

Hello there,

I have implemented my Socket.io server using multiple nodes. My script starts 4 Socket.io servers at a time, and all these servers are connected via the MongoDB adapter. An Nginx server works as a reverse proxy between my servers and the users, and my clients are connecting to my server using the WebSocket transport because the Nginx sticky sessions never worked for me for whatever reason. Due to the shortage of time, I skipped setting up the sticky sessions at that moment and proceeded with only WebSocket transport.

One other thing worth mentioning here is that my local development server, and the production server, both are connected to the same capped collection of MongoDB for listening to the adapter events.

Now the problem is, whenever I try to connect Admin UI with my Socket.io server, it connects successfully. But it only shows me stats for that one specific instance of Socket.io server with which Admin UI is connected. To my surprise, I see my local development (Socket.io) server, when it is running locally, listed in the list of servers. Although I connect my Admin UI specifically with the URL of my production app URL.

Can you please help me figure out what is happening here? Why my all production servers are not being listed in Admin UI, and why am I seeing my local dev server in the list of production servers?

No data but seems to be logged in correctly

Hi there,
I wanted to use this nice admin UI but had some issue. The status is "Connected" in green, but I have literally no data, no client, no server... everything is 0

What I check:

  • correct bcrypt hash: I made sure to use node.bcrypt.js to hash the pwd
  • the login POST request response is "ok"
  • not linked to adblock, same on chrome and firefox

Cf the screenshot:
Capture d’écran 2021-09-06 à 23 02 38

And the WS request transfer the following:
Capture d’écran 2021-09-06 à 23 05 13

I've installed :
"@socket.io/admin-ui": "^0.2.0", "socket.io": "^4.1.1", "socket.io-client": "^4.1.1",

and I'm using node 16.

Is there anything I'm missing?

Admin UI doesen't seem to work with auth

If i try to set auth to false it all works as a charm but as soon as i set up auth it stop working. In particoulpar:

  • If i try to connect to https://myserver.com/admin with the correct credentials it gives me "Invalid credetials"
  • If i try to connect to https://myserver.com with the correct credentials it let me in but i have no data in the admin ui

I've also tried to specify the namespace of /admin with the auth being set but it still gives me invalid credentials.

I'm using NEXT.js setting up the handler for next in an express server (in the same place i've also set up socket.io.

Add UI grid filtering options

Hi,
I want to filter on specific socket id in sockets screen. So, it would be great if you can add a grid filter on the socket id column. Same concept can be applied to other screens as well to help with identifying specific entities if there are 1000's of entities shown in the grid.
image

Redis-adapter -> reject(new Error("timeout reached while waiting for fetchSockets response"))

hello.

I am configuring a socket.io server using pm2 and redis-adapter.
I'm using express to bring up the admin ui on the same port as socket.io.

public async connect(http_server: http.Server): Promise<void> {
    try {
      SocketIO.server = new Server({
        cors: {
          origin: "*",
          credentials: true
        },
        transports: ['websocket'],
        allowUpgrades: true,
      });
      const pubClient = createClient({
        socket: {
          host: process.env.REDIS_IP,
          port: <number><unknown>process.env.REDIS_PORT,
        },
        password: process.env.REDIS_PASSWORD
      });
      const subClient = pubClient.duplicate();
      await pubClient.connect();
      await subClient.connect();
      SocketIO.server.adapter(createAdapter(pubClient, subClient));
      SocketIO.server.attach(http_server);

      instrument(SocketIO.server, {
        auth: {
          type: "basic",
          username: "...",
          password: "^__^", 
        },
        mode: "development",
        serverId: `${hostname()}#${process.pid}`,
      });

    } catch (err) {

      process.exit(1);
    } 
  }

run it like this, it works without any problems, but when you connect to http://localhost:3900, the following message occurs after about 3 to 5 seconds.

D:\Project\socket\node_modules\@socket.io\redis-adapter\dist\index.js:615
                    reject(new Error("timeout reached while waiting for fetchSockets response"));
                           ^
Error: timeout reached while waiting for fetchSockets response
    at Timeout._onTimeout (D:\Project\socket\node_modules\@socket.io\redis-adapter\dist\index.js:615:28)
    at listOnTimeout (node:internal/timers:564:17)
    at processTimers (node:internal/timers:507:7)

https://admin.socket.io <- this url is Same.. the server crashes.

What's the problem? 😢

npm version

"dependencies": {
    "@socket.io/admin-ui": "^0.5.1",
    "@socket.io/redis-adapter": "^8.0.1",
    "express": "^4.18.2",
    "redis": "^4.0.4",
    "socket.io": "^4.5.4"
  },

Please release 0.4.0 on npmjs

Hi

Please release the current version 0.4.0 on npmjs so that the npm can be used :)

The latest version is still 0.3.0

Best,
Thomas

TypeError: Cannot set properties of undefined (setting 'transport')

Issue:
Local development in VS Code runs without problems or crashes.
However, when I upload the application to a server, it runs until a Socket.io connection is established or the connected web page is refreshed.
I don't know if this relates to the admin UI specifically as in the filepath below or if this is a Socket.io issue in general.
Perhaps this also has to do with the middleware which holds up a request until an action has completed so that non-existent data cannot be accessed.

// middleware is executed on every request
var Map = require('file')

module.exports = (io, socket) => {
    socket.use(async (packet, next) => {
        var key = socket.handshake.auth.key
        var data = Map.get(key)
    
        while(!data.action) {    // true for finished or false for loading
            await new Promise(resolve => setTimeout(resolve,10))
        }
        socket.data = data
        next()
    })
}

Serverconsole:

/usr/src/app/node_modules/@socket.io/admin-ui/dist/index.js:233
socket.data._admin.transport = transport.name;
^

TypeError: Cannot set properties of undefined (setting 'transport')
at Socket.<anonymous> (/usr/src/app/node_modules/@socket.io/admin-ui/dist/index.js:233:42)
at Socket.emit (node:events:390:28)
at WebSocket.onPacket (/usr/src/app/node_modules/engine.io/build/socket.js:214:22)
at WebSocket.emit (node:events:390:28)
at WebSocket.onPacket (/usr/src/app/node_modules/engine.io/build/transport.js:92:14)
at WebSocket.onData (/usr/src/app/node_modules/engine.io/build/transport.js:101:14)
at WebSocket.<anonymous> (/usr/src/app/node_modules/engine.io/build/transports/websocket.js:20:19)
at WebSocket.emit (node:events:390:28)
at Receiver.receiverOnMessage (/usr/src/app/node_modules/ws/lib/websocket.js:1022:20)
at Receiver.emit (node:events:390:28)

Node.js v17.3.1

Multiple namespaces

We have an option like give namespace,

instrument(global.io, {
    auth: false,
    namespaceName: '/',
});

What if we have dynamic namespaces?

Feature request - callback for authentication

Hi

I have embedded the ui in my app which features a role-based authentication (roles "user" and "admin"). As there are more then one user which should have the ability to connect to the ui, is there a callback or similar i can use for authentication?

I thought about connecting the ui to my userRole so that only users with userRole.admin can connect (if they authenticate correctly).

Best,
Thomas

Error serialising sockets with session stores

I have an application that shares an express session with socket.io. The session is backed by a redis store. The admin runs fine when the socket.io server starts but crashes when a client connects to the socket.io server.

../app/node_modules/notepack.io/lib/encode.js:256
      throw new Error('Could not encode');
      ^

Error: Could not encode
    at _encode (../app/node_modules/notepack.io/lib/encode.js:256:13)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:162:19)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:162:19)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:162:19)
    at Object.encode (../app/node_modules/notepack.io/lib/encode.js:261:41)
    at RedisAdapter.broadcast (../app/node_modules/socket.io-redis/dist/index.js:313:33)
    at BroadcastOperator.emit (../app/node_modules/socket.io/dist/broadcast-operator.js:113:22)
    at Namespace.emit (../app/node_modules/socket.io/dist/namespace.js:168:73)
    at Namespace.<anonymous> (../app/node_modules/@socket.io/admin-ui/dist/index.js:231:24)
    at Namespace.emit (events.js:315:20)

From what I gathered, the crash happens because the socket serialisation in

handshake: socket.handshake,
contains redis related things in socket.handshake:

{
...
sessionStore: RedisStore {
     _events: [Object: null prototype] {
       disconnect: [Function: ondisconnect],
       connect: [Function: onconnect]
     },
     _eventsCount: 2,
     _maxListeners: undefined,
     prefix: 'sess:',
     scanCount: 100,
     serializer: Object [JSON] {},
     client: RedisClient {
...
}

I'm not quite sure where that sessionStore is added to socket.handshake but maybe socket.io-admin could filter the handshake object based on its interface in https://github.com/socketio/socket.io/blob/b84ed1e41c9053792caf58974c5de9395bfd509f/lib/socket.ts#L64?

RedisStore saveSession function got error

Hi, contributors

I have a problem with RedisStore when trying to save the session for socket connection to Redis, the store got an error like the below.

image

I really think, this function causes it:
image

Details

  • node: v16.15.1
  • socket.io: ^4.5.1
  • redis: ^4.1.0
  • @socket.io/admin-ui: ^0.4.0
  • @socket.io/redis-adapter: ^7.2.0

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.