A project I'm working needed an event fired from one user to go directly to another user and fire a JavaScript event. It took some playing around but it turned out that it was pretty easy thanks to the current modules. I did notice a shortage of documentation so here is a general outline of how I did it. Of course, if anyone has suggestions on doing it better or more efficiently, please post!

Modules that needed to be enabled:
NodeJS, NodeJS Config, NodeJS Ajax, NodeJS Notify

So I started with what worked, NodeJS Notify allowed a message to be sent directly to a user with : nodejs_send_user_message($uid, $subject, $body)

When I looked at its details I found a simple object structure being passed to the Node server:

$message = (object) array(
    'data' => (object) array(
      'subject' => $subject,
      'body' => $body,
    ),
    'channel' => 'nodejs_user_' . $uid,
    'callback' => 'nodejsNotify',
  );
  nodejs_enqueue_message($message);

Specifically, the callback in the message peaked my curiosity. Upon examining the JS file for the notify module, I noticed it was pretty simple:

Drupal.Nodejs.callbacks.nodejsNotify = {
  callback: function (message) {
  	//console.log(message);
  	if (message.callback == 'nodejsNotify') {
  	    var notifyTime = Drupal.settings.nodejs_notify.notification_time;
  	    if (notifyTime > 0) {
  	      $.jGrowl(message.data.body, {header: message.data.subject, life:(notifyTime * 1000)});
  	    }
  	    else {
  	      $.jGrowl(message.data.body, {header: message.data.subject, sticky:true});
  	    }
  	}
  }
};

You'll see a slight modification I made to actually CHECK the callback function since in my case it didn't seem to matter. Perhaps this should be in a bug report too but I haven't got there yet.

So with this, I created my own js file in my module and loaded it with this call, again, no documentation on this but it worked. Putting that JS in a regular js file didn't work at all :

/**
 * Implements hook_nodejs_handlers_info().
 */
function mymodule_nodejs_handlers_info() {
  return array(
    drupal_get_path('module', 'mymodule') . '/nodejs.mymodule.js',
  );
}

function mymodule_sendsomecustomevent($uid) {
  $message = (object) array(
    'data' => (object) array(
      'somecustomdata' => 'http://www.google.ca'
    ),
    'channel' => 'nodejs_user_' . $uid,
    'callback' => 'myowncallback',
  );

  Nodejs::enqueueMessage($message);
}

The second function is my menu callback I run from the source browser that will trigger the nodeJS event on the recipient browser with the new JS we'll write.

Here is what my new JS file looked to handle the new callback:

Drupal.Nodejs.callbacks.myowncallback = {
  callback: function (message) {
  	//console.log(message);
  	if (message.callback == 'myowncallback') {
  	    // Do whatever I want on the client's browser from here
            alert(message.data.somecustomdata);

  	}
  }
};

Hope this helps someone build a really cool application. Please post any feedback you might have.

Comments

j2r’s picture

Thanks for the article.

J2R

N20’s picture

thank you, exactly what i looked for

bjuncosa’s picture

For me, I got a little worried when I saw that you had your callback logic in a JS file added to the page via the handers_info hook. Mostly because I'm using Backbone, and I'd like the callback logic to be integrated with the Backbone models, so the views can update based on model change events.

Anyway, although I got your example to work using the handlers_info hook, I was also able to use the same exact client-side JS in a script file not added through the handlers_info callback. Is it possible that the prerequisite libraries (drupal.js and nodejs.js) weren't loaded yet before you tried to add your callback?

This was a good starting point for me, thanks.

imunklovarian’s picture

I still can't get the point, where the form is ? could you give more detail example !

thanks