Thanks for the amazing integration module!

We're trying to use it on a production server (with DrupalChat and some custom JS) and have run into what we think is a garbage collection issue. The debug logs were showing that every time a user logged in or out, which sent a message to all the other authenticated users, it spawned a number of 'failed' messages:
publishMessageToClient: Failed to find client jxIaVp0yly6BiZKtcEui

It seemed like the NodeJS presence table wasn't been maintained and a number of client sessions who had left were still being tracked.

Our temporary solution is to restart NodeJS every night but I'm not even sure if this helps much. Has anyone seen anything like this or have any suggestions on places to look?

Thanks so much!

Comments

j2r’s picture

What i understand from the module is: It is creating a channel for every logged in user and when user logout the channel is closed.

So it might depend on how you are sending the messages to all the other user.

julien66’s picture

Hi
First of all let me give a big thank and applause for the dev / maintainer team of this module.
The code and the functionnality allowed are supermassive and I'm currently having great fun learning around it .

Back to this topic, I'm almost sure that what is described at #1 is a real bug.
At logout the presenceNotification event is only fired if I use Firefox. Not Working in Chrome (up to date).
A simple test is to login / logout user from different browsers and to check the presence table or to read the debug mode of your node server.

I'm digging a bit more and will report if I find something.
++

julien66’s picture

I finally figured out that for some reasons 'disconnect' event is never fired at logout with some browsers (not related to the transport protocol Chrome + IE9 are both affected). I don't know exactly why this is happening at the moment so I can't fix it on a proper way.

However I think I came with a quick fix thanks to the logoutUser and the cleanupSocket fonction.
I'm running a cleanupSocket again inside logoutUser and all is looking better.
Cheers !

var logoutUser = function (request, response) {
  var authToken = request.params.authtoken || '';
  if (authToken) {
    console.log('Logging out http session', authToken);
    // Delete the user from the authenticatedClients hash.
    delete authenticatedClients[authToken];
    // Destroy any socket connections associated with this authToken.
    for (var clientId in io.sockets.sockets) {
      if (io.sockets.sockets[clientId].authToken == authToken) {
        cleanupSocket(io.sockets.sockets[clientId]); // Perform a better cleanup instead of the fast way below.
        /*delete io.sockets.sockets[clientId];
        // Delete any channel entries for this clientId.
        for (var channel in channels) {
          delete channels[channel].sessionIds[clientId];
        }*/
      }
    }
    response.send({'status': 'success'});
    return;
  }
  console.log('Failed to logout user, no authToken supplied');
  response.send({'status': 'failed', 'error': 'missing authToken'});
};
Anonymous’s picture

Version: 7.x-1.0-rc1 » 7.x-1.x-dev

thanks, i'll look in to this. any chance you could post a patch against 7.x-1.x-dev ?

julien66’s picture

Status: Active » Needs review
StatusFileSize
new798 bytes

Sure ! Here is a patch for the issue I found. It took me quite long to answer as I just learnt how to use git.
We should better find out the reason why the "disconnect" event is not being trigged on some browser. Still no clue here.
++

julien66’s picture

There is another trouble : When a registered user close his browser, he is nicely disconnected and erased from the node_js presence table (so far so good).

Problem is happening when the user is revisting the website again with a "still valid session". Although the sendPrensenceChangeNotification is logged in nodejs, the real insert inside nodejs_presence table is not done ! (He should be back to "present"...).
I'm investigating on this right now and will report if I find something.

julien66’s picture

StatusFileSize
new2.32 KB

Thanks again for the good work !
Fixing the issue was quite easy : I set a messageType 'userOnline' on the module message handler and just sendMessageToBackend() from node server when needed.

=> Here is a global patch that fix the nodejs_presence table issues I found. Fix for #5 & #6 are included. I'll test more if I can find something else but the presence table now looks nicer.
We surely need to rename this issue title as the described problem wasn't related to garbage collection (so far imo).
++

julien66’s picture

StatusFileSize
new2.37 KB

I've been to fast to publish the #7 patch.
This one is way better.

sazcurrain’s picture

Hi,

Any clue of why the disconnect event isn't fired?

I'm using this module with drupalchat, and is indispensable that the disconnect event to be fired, in order to update the users list in the chat window.

This works fine with Firefox, but Opera and Chrome only fires the event when Refreshing/Closing the browser, but not when login out from Drupal.

I suspect this have to be related with the socket.io library, but i have no clue from where to start looking.

Any help will be wellcome =)

fraweg’s picture

Hello,

I have the same issue with the drupalchat module. For me the patch #8 didn't solve the issue.

Any help is welcome..

Thanks in advanced

FRank

bjuncosa’s picture

I can confirm this bug, and how to replicate. The browsers I have tested are: Chrome (Mac), Safari (Mac), and FireFox (Mac). Chrome and Safari behave the same.

For the sake of simplicity, you can run these tests running only the included nodejs_notify module. Before running the test, it'd be good to log out of the Drupal site, clear out the nodejs_presence table, and restart node.

  • When logging in, the user is added to the presence table.
  • When logging out, FireFox is the only browser of the tested that removes the user from the presence table.
  • If logged in, navigating to another site will remove the user.
  • Returning to the Drupal site will NOT re-add the user. To do this, log out, and log back in (start the process all over again).

When returning to the Drupal site, Node reuses the existing authentication. This prevents any "new user" messages / presence table updates. As pointed out above, I do not believe this is garbage collection related. Rather, it seems related to the disconnect / reusing of authentication logic.

This has other side-effects. One being that the Node server will attempt to send messages to clients that didn't properly disconnect.

Anonymous’s picture

Anonymous’s picture

Status: Needs review » Fixed

please reopen if this does not fix your issues.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

wanisabreen_07’s picture

Version: 7.x-1.x-dev » 6.x-1.0

where should i paste this patch?

cmonnow’s picture

Issue summary: View changes
Status: Closed (fixed) » Active

Hi,

I might open another issue queue but it appears very likely to me that the issue I'm experiencing in 7.x-1.7 has the exact same cause.

As previously mentioned, the remaining issue (other than the fixed logout bug) is that when a user closes a page or navigates to a new page the nodejs_presence table will delete the existing entry in the nodejs_presence table but not re-create a new one, causing the user to appear away for third-party modules that exploit this table.

As suggested by bjuncosa, the error occurs because server.js sees a familiar existing authentication token and doesn't have any code in place to update the backend. I have a seemingly working fix for this but I wasn't sure if what we're seeing is a specific configuration bug (how could this bug exist for so long with so little fuss?) or a general bug (since I could at least fix the failure upon navigation between pages (but not recover from a page close) by using the raw IP for the page with a matching back end IP in the config js e.g. 192.168.1.7 rather than example.com).

Here's a code people can try. Just add a few lines to setUserOffline in the server.js file so that when cleanupSocket is called upon client disconnection and subsequently checkOnlineStatus is called (in an interval loop) => that will then induce setUserOffline where we will be ready with some new lines to delete that user's session authentication token(s).


/**
 * Sends offline notification to sockets, the backend and cleans up our list.
 */
var setUserOffline = function (uid) {
  sendPresenceChangeNotification(uid, 'offline');
  delete onlineUsers[uid];
  //remove authentication token
    for (var authToken in authenticatedClients) {
      if (authenticatedClients[authToken].uid == uid) {
        delete authenticatedClients[authToken];
      }
    }
  sendMessageToBackend({uid: uid, messageType: 'userOffline'}, function (response) { });
}
cmonnow’s picture

Priority: Normal » Major
cmonnow’s picture

Version: 6.x-1.0 » 7.x-1.x-dev

I just noticed the version was originally 7.x-1.x-dev where I'm experiencing related issues so I've changed it back. Is there a way to assign multiple versions or is duplication necessary?

  • Commit 61be29e on 7.x-1.x, 8.x-1.x, 8.x-1.x-head by beejeebus:
    #1823254 by julien66: handle logout and socket cleanup better.