I'm just trying out this code as a simple intro to nodejs integration. I've found that the first time a user tries to connect to a chatroom they are not established in the channel and although their posts go to other members they do not receive anything. There is a particular problem with the first participant who also causes the chat to be created as they get an error message 'Undefined index: users in nodejs_get_content_channel_users() (line 60 of /var/www/html/mbaso/sites/all/modules/contrib/nodejs/nodejs.module)'.

Both problems are caused because the chat is created and the user added by the server before the user has been authenticated by nodejs. The user is only authenticated once the page has loaded and the socket.io client has had a chance to run.

Not sure if there is a simple fix yet.

Comments

slv_’s picture

Hey Dippers, thanks for reporting this. It's actually 1 thing I has a todo, because I'm aware of that warning message and wanted to to look into it. That seems something to be fixed on the nodejs module, as it should let one know that there are no users yet, which seems to be the case when that gets displayed.

On what respects to nodejs_chat, you've probably described well the reason why that's happening, but I haven't had the chance to look into that yet (in fact, not even sure I had noticed that), but I'll definitely do, so thanks very much for opening the issue.

Will add some info once I reproduce it locally and figure out what is the best way to fix it. Right now the first option that springs to mind is a call to the back-end after initialising a chat on the client, just to trigger the nodejs_add_user_to_channel() function. If not for all, at least setting a var in Drupal.settings so that it's only called for the first user.

Anyhow... will look into this. Thanks!

dippers’s picture

I've looked at this some more but cannot find an elegant solution. It looks like a backend request and add-user-to-channel response is the most likely option but that doesn't solve the problem of the error message generated because the chat room is empty when it is first created.

It seems the nodejs module is not really structured for this type of implementation as it closely couples drupal and nodejs whereas I was looking for a solution that closely couples the client and nodejs with drupal only involved with authentication.

I really want the client to initiate the addition of the user to the chat. With this implementation that is not possible because the client doesn't know when they have been authenticated, it doesn't know the user's uid and it cannot send a 'join' request directly to nodejs.

I think I'm going to have to look at a custom implementation using the ideas suggested here.

slv_’s picture

Haven't had the time to look into this yet, but I'm confident there's some way to get the client to initiate the addition of the user to the chat. I wasn't aware of that blog post (series) so will be definitely checking them out, thanks! On the warning thing, I'll be committing a fix for that on the nodejs module. Regardless of whether there's a clear drawback in there, as I call the add_user_to_channel and the channel_users function still returns nothing, it should be fixed to avoid the warning when a channel is empty, and return an empty array instead.

Don't hesitate to keep in touch if you make any more findings on this, or if you start your custom project.

Leaving this open as it's still an issue I have to look into.

slv_’s picture

Status: Active » Fixed

First of all: This is fixed now and committed to dev branch. The server.js extension for the module contains new code required for this to work, so make sure to replace the old extension with the new one (as well as flushing js cache).

I've been investigating this and studying a bit more the nodejs.module and server.js workflow. Since the user is not authenticated by the server until he's loaded a page with nodejs on it, the add_user_to_channel() function obviously can't work in 100% cases.

However, when "Drupal.Nodejs.runSetupHandlers" is run on nodejs.js, we can say the user has been authenticated, so we can trigger a call to the server to get the user added to the channels we want. The fix includes this in the initialiseChat() function, which triggers the call when needed. (I was already implementing a setupHandler to call the initialiseChat() function.

On the drupal side, I've added some code to make sure the current user is always counted as on the channel, to get it on the connected users list, so this bugs caused by the client-authentication happening on the browser (which makes absolute sense, since users need to be assigned a socket on the node server) should be fixed now.

PD: The back-end call after initialising the chat was a possibility indeed, but seemed awkward to me for this scenario at least. Also, implementing hook_nodejs_user_channels() and returning specific channels would fix the problem as well, even if the user hasn't been added directly to a channel but has access to it through this hook (which in the end is a way of calling add_user_to_channel with as many channels as you want, but being sure that the user is being authenticated). Issue with that hook is that it's not really useful for the nodejs_chat module, because I work with dynamic channel ids, so would need to add channels with a wildcard, like "Chat__*", and there's no support for that, so I discarded this option as well.

Hope that fixes the problem and you still find this chat interesting. Thanks! ;)

Status: Fixed » Closed (fixed)

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