Using Drupal Content Channel Tokens with Nodejs
You've decided to add a bit of Node.js functionality to your Drupal site using the [Drupal Nodejs Module](https://drupal.org/project/nodejs). After [some reading](http://theoleschool.com/blog/module-development-nodejs-integration) you realize you need to be setting up user message channels using hook_nodejs_user_channels
or possibly nodejs_add_user_to_channel
. This allows your application to send socket messages to groups of users. Great! But you're writing no simple application. You want to go one step further and manage these channels based not only on some property of the user object, but all users who may be currently viewing a particular Drupal served page. Suddenly the typical user channels no longer cut it. Try as you might, you'll find yourself quickly descending into channel management hell. There has got to be a better way. Thankfully content token channels are here to help.
###Send a Message Based on the Content Being Viewed
You can think of content token channels as a per page (or piece of content) channel subscription. This differs from the user channels in that it targets users who are currently viewing a specific page rather than users targeted by some property of the user object (regardless of where they are on the site).
There are two main PHP functions to implement a token channel. nodejs_send_content_channel_token
to generate a token channel for a given piece of content, and nodejs_send_content_channel_message
to send a message to users subscribed to a given content channel.
To illustrate this lets assume we want to create a channel to send user messages when they are viewing a Drupal node of type _page_. To begin we will need to setup our content channel for that node type. A good place to do this would be hook_node_view
which fires when a user views a node.
function example_node_view($node, $view_mode, $langcode) {
if($node->type == "page") {
nodejs_send_content_channel_token('page_node_channel');
}}
Now every time a node of type _page_ is viewed the Node.js server is notified of the _page\_node\_channel_ content channel. Node.js then adds the channel to the user for whom the page was rendered.
From here if we wish to send a message to all of the users viewing a node of type _page_ we make a simple call to nodejs_send_content_channel_message
. When and where you choose to fire this message is up to you. Possibly you want to notify users if the page they are viewing has been updated (hook_node_update
), a user logs in (hook_user_login
), or some new content was added (hook_node_insert
).
// Build a message object$message = new stdClass();$message->channel = 'page_node_channel';$message->data['body'] = 'Hello World!';// Send the message to the channel we created
nodejs_send_content_channel_message($message);
And that's about it! When nodejs_send_content_channel_message
fires our message will be broadcast to all users subscribed to the page_node_channel. In this case all users who are currently viewing a node of type _page_. This message behaves like any other on the Node.js side, so you could send it to a custom callback handler, as mentioned [in an earlier post](http://theoleschool.com/blog/module-development-nodejs-integration).
###Token Messages From an Node.js Extension
If you are writing a Node.js server extension and wish to send a message to a content channel, it is worth noting that there is no immediately exposed functionality to do this. However, Node.js server extensions are aware of what the content channels are via config<span style="color: #339933;">.</span>tokenChannels
. This allows us to mimic the functionality of the Drupal Node.js server with a helper method in our server extension.
function sendMessageToTokenChannel(message, config) {
if (!message.hasOwnProperty('channel')) {
console.log('publishMessageToContentChannel: An invalid message object was provided.');
return;
}
if (!config.tokenChannels.hasOwnProperty(message.channel)) {
console.log('publishMessageToContentChannel: The channel "' + message.channel + '" doesn\'t exist.');
return;
}
for (var socketId in config.tokenChannels[message.channel].sockets) {
config.publishMessageToClient(socketId, message);
}}
Adding this http://www.aqabazone.com/sb/cialis.php method to your server extension, will allow you to send messages to a content channel, by passing the message and config objects from within your exports<span style="color: #339933;">.</span>setup
function.
Using content token channels has greatly simplified several of the Drupal/Node.js projects I have done. However, it wasn't immediately apparent that this functionality existed. So I hope this helps to further clarify the capabilities of this module.