array( 'description' => t('Send node over stomp to anyone listening.'), 'type' => 'node', 'configurable' => TRUE, 'hooks' => array('any' => TRUE), ), ); } // Implements hook_action_form for configuration. // Two options are server address, and url. Not optional. function demo_stomp_send_action_form($context) { $form['address'] = array( '#title' => t('Server Address'), '#type' => 'textfield', '#description' => t('The STOMP server address, in the form tcp://localhost:61613, or ssl://localhost:61613.'), '#default_value' => isset($context['address']) ? $context['address'] : '', ); $form['url'] = array( '#title' => t('URL'), '#type' => 'textfield', '#description' => t('The URL the clients are registered on.'), '#default_value' => isset($context['url']) ? $context['url'] : '', ); return $form; } // Implements hook_action_submit. function demo_stomp_send_action_submit($form, $form_state) { return array('address' => $form_state['values']['address'], 'url' => $form_state['values']['url']); } // This is the action. It uses the stomp client from, http://stomp.codehaus.org/PHP function demo_stomp_send_action(&$node, $context) { $host = $context['address']; $url = $context['url']; $message = $node->field_words[0][value]; // import client require_once 'Stomp.php'; // instantiate new instance $con = new Stomp($host); //connect $con->connect(); // send message to anyone subscribed to the channel $con->send($url, $message); // disconnect $con->disconnect(); } // implements hook_form_alter function demo_form_alter(&$form, &$form_state, $form_id) { if ($form_id == chat_node_form){ drupal_add_js('misc/jquery.form.js', 'module', 'header', FALSE, TRUE, FALSE); drupal_add_js('sites/all/modules/slyngit/Orbited.js', 'module', 'header', FALSE, TRUE, FALSE); drupal_add_js('sites/all/modules/slyngit/json.js', 'module', 'header', FALSE, TRUE, FALSE); drupal_add_js(' document.domain=document.domain; Orbited.settings.port = 9000; Orbited.settings.hostname = "slyngit.com"; TCPSocket = Orbited.TCPSocket;', 'inline', 'header', FALSE, TRUE, FALSE); drupal_add_js('sites/all/modules/slyngit/stomp.js', 'module', 'header', FALSE, TRUE, FALSE); // This definetly shouldn't be inline drupal_add_js(' Drupal.behaviors.demo = function(context) { // cleaning up for visitors context.getElementById("edit-preview").style.visibility = "hidden"; context.getElementById("block-user-0").style.visibility = "hidden"; context.getElementById("block-user-1").style.visibility = "hidden"; var options = { clearForm: true , //resetForm: true, }; //demo wouldn\'t really be interesting without ajax posting. $("#node-form").ajaxForm(options); // instantiate the client object stomp = new STOMPClient(); // add all the call backs stomp.onopen = function() { //alert("Transport opened"); }; stomp.onclose = function(code) { alert("Transport closed (code: " + code + ")"); }; stomp.onerror = function(error) { alert("onerror: " + error); }; stomp.onerrorframe = function(frame) { alert("onerrorframe: " + frame.body); }; // Two callbacks here, once we established a connection // subscribe to some stuff. The urls are entirely arbitrary // and could be utilized in many ways. For example, you could have // a channel that anyone could listen on, the way this is set up currently // to allow for mass updating, or you could have private channels // like /SESSID* that are personal. Authentication is also supported // although not used here. stomp.onconnectedframe = function() { stomp.subscribe("/wall"); stomp.subscribe("/logo"); }; // This is the meat of the matter. This is where we decide what to do // with the recieved data. Haven\'t quite figured out how to handle // different responses from different channels in a cleaner way yet. // Although I\'m thinking that wraping all data in JSON and adding a // url attribute before sending would take care of it. stomp.onmessageframe = function(frame) { // If you post a url on the wall it will try to show with the kittens // Not the best design. if (frame.body.substring(0,7) == "http://") { image = context.getElementById("logo"); image.setAttribute("src", frame.body); image.setAttribute("width", "200"); image.setAttribute("height", "200"); } else{ // This is obviously not the way to handle this, but I just wanted // to get something up and running as a demo. The views api seems // to be missing quite a bit of documentation. tbody = context.getElementsByClassName("views-table")[0] .getElementsByTagName("tbody")[0] even_count = context.getElementsByClassName("even"); odd_count = context.getElementsByClassName("odd"); if (odd_count.length > even_count.length){ // This handles the case for the first post where there are no // even tags yet. child = odd_count[0].cloneNode(true); child.setAttribute("class", "even"); child.getElementsByTagName("td")[0].innerHTML = frame.body; tbody.appendChild(child); } else{ child = odd_count[0].cloneNode(true); child.getElementsByTagName("td")[0].innerHTML = frame.body; tbody.appendChild(child); } }; } // After all the callbacks are added we make our connection stomp.connect(location.hostname.split(":")[0], 61613); }; ', 'inline', 'header', FALSE, TRUE, FALSE);}} // Stuff for the kittens function demo_menu() { $items = array(); $items['kittenwar'] = array( 'title' => 'KITTEN WAR', 'access callback' => 'kitten_war_access', 'page callback' => 'kitten_war_post', 'type' => MENU_NORMAL_ITEM, ); return $items; } // Normally this would just be an action but I don't want to actually process // any kittens function kitten_war_post() { require_once 'Stomp.php'; $con = new Stomp('tcp://localhost:61613'); $con->connect(); $con->send('/logo',$_POST['KITTEN']); $con->disconnect(); } function kitten_war_access() { //we need all the help we can get return TRUE; }