最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Count number of online users with nodeJS and Socket.io without duplicates - Stack Overflow

programmeradmin0浏览0评论

I'm having trouble displaying the correct amount of online users. A question similar to this have shown me that I can count the users this way:

var count = 0
  socket.on('connection', function(client) {
  count++;
  client.broadcast({count:count})
  client.on('disconnect', function(){
    count--;
  })
})

The issue I'm constantly running into with that method is that when a user happens to reload the page too quickly, the counter pulls in too much it can throw out.

As you can see, on the right side of the image, a user spammed the reload and it caught more users online than there actually is. (There was only one user on the server at this time)

My question is is there a better or more reliable way to count the exact amount users online without the extra 'virtual users', without using the users++/users-- method?

I'm having trouble displaying the correct amount of online users. A question similar to this have shown me that I can count the users this way:

var count = 0
  socket.on('connection', function(client) {
  count++;
  client.broadcast({count:count})
  client.on('disconnect', function(){
    count--;
  })
})

The issue I'm constantly running into with that method is that when a user happens to reload the page too quickly, the counter pulls in too much it can throw out.

As you can see, on the right side of the image, a user spammed the reload and it caught more users online than there actually is. (There was only one user on the server at this time)

My question is is there a better or more reliable way to count the exact amount users online without the extra 'virtual users', without using the users++/users-- method?

Share Improve this question edited Nov 29, 2017 at 21:07 Ackados asked Nov 29, 2017 at 20:59 AckadosAckados 951 silver badge9 bronze badges 1
  • 1 You could always check their IP addresses. – Obsidian Age Commented Nov 29, 2017 at 21:03
Add a ment  | 

2 Answers 2

Reset to default 4

If they're logging in as a user, then you should authenticate them to the socket. Use that authentication to see if they already have a session, and disconnect them decrementing the count, before you increment it again with the new session.

An example below. The clients objects stores the connected clients, with values being the sockets they're connected to.

var clients = {};
socket.on('connection', function(client) {
  //Authenticate the client (Using query string parameters, auth tokens, etc...), and return the userID if the user.
  var userId = authenticate(client);

  if ( !userId ) {
    //Bad authentication, disconnect them
    client.disconnect();
    return;
  }

  if (clients[userId]) {
    //They already have a session, disconnect
    clients[userId].disconnect();
  }

  //Set session here
  clients[userId] = client;

  client.broadcast({count: Object.keys(clients).length})
  client.on('disconnect', function(){
    delete clients[userId];
  })
})

Could do this pretty cleanly with the Observable pattern (using RxJS v5 here):

const { Observable } = require('rxjs')

const connections = Observable.fromEvent(socket, 'connection').mapTo(1)
const disconnections = Observable.fromEvent(socket, 'disconnect').mapTo(-1)

// emit 1 for connection, -1 for disconnection
Observable.merge(connections, disconnections)
  .scan((total, change) => total + change, 0) // emit total
  .subscribe(count => client.broadcast({ count }))
发布评论

评论列表(0)

  1. 暂无评论