XPages and Bluemix: How to create a Websockets message without being connected to the application

In this article I demonstrate how to create a Websocket message to be broadcast, from a website which is not connected to the Websocket directly. This will be achieved by using a http POST request of the message to a node.js server hosted on Bluemix and having that server then emit a Websocket message out to the application.

Introduction

In the previous article I demonstrated how to create an XPages chat client using a Bluemix hosted node.js server. I was able to do this by porting the node.js example to an XPage (xSocket.xsp). What I wanted to figure out (thank you Stack Overflow) was how to trigger a Websocket message to be sent out without using the Websocket socket.io JavaScript client.

Reference articles

This article is based on information already published on the following blog posts:

POSTing to a node route

In the Watson translation service example article I discussed how to create a new POST route within your node application using the simple express construct “app.post”.


var cors = require('cors');
app.use(cors());

var corsOptions = {
  origin: 'http://copper.xomino.com'
};

app.post('/xpages', cors(corsOptions), function(req, res){
  .....
});

In a similar fashion in this example I am going to POST data from the copper.xomino.com website and therefore I need to add the cors code to the application to allow this.

Looking at the message payload

If we look at the client.js file from the original node.js Bluemix example blog post we can see that the message which is sent to the websocket looks like this

    var msgField = $('#msg'),
    data = { msg: msgField.val(), nickname: nickname, when: new Date() };

So our target is to recreate that same data Object and send it through to the server socket emitter in the same format.

Creating the POST data

Once again learning from the previous Watson example the code for this is relatively simple. We create the data Object with a nickname and text value and then POST them to the xominosocket.mybluemix.net site. Logging the response from the server

var data = {
	nickname: 'marky ajax',
	text: 'Sample POST from AJAX'
}
console.log(data)
$.ajax({ url:
	"http://xominosocket.mybluemix.net/xpages",
	type: "POST",
	data: data
}).done(function( msg ) {
	console.log( msg);
});

Modifying the node.js code

The node.js code from the previous article needs to be updated in a number of ways.

The Watson Translation example used a version of express 3.x. Version 4 is more streamlined and does not contain a lot of middleware. When we attempt to POST data to the node server it cannot be understood because it is encoded by the web browser (by default). For his we need to add the npm module body-parser (not forgetting to include it in the package.json).

The new package.json looks like this

{
  "name": "xominosocket",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.10.1",
    "jade": "^1.7.0",
    "redis": "^0.10.3",
    "socket.io": "^1.2.0",
    "cors": "2.4.2",
    "body-parser": "1.9.2"
  }
}

The app.post also needs to be able to parse the incoming POST and then re-purpose this into a socket emit event. We do this as follows. I also added a check to make sure the req.body was coming through. This was failing before I realized I needed body-parser.

// Handle the form POST containing the text and nickname
app.post('/xpages', cors(corsOptions), function(req, res){
  var request_data = {};

  console.log(req.body)

  if (req.body){
    request_data = {
      'txt': req.body.text,
      'nickname': req.body.nickname
    };
  } else {
    request_data = {
      'txt': 'this failed',
      'nickname': 'Not this guy'
    };
  }

  var data = { msg: request_data.txt, nickname: request_data.nickname, when: new Date() };
  io.sockets.emit("msg", data);
  res.send(data);
});

Testing the new capability

For the purposes of this article I am only going to show the example in Firebug console. As you can see from the code on the right we are posting to the xominosocket site. On the left you can see the communication was successfully sent to the site, the response and the headers:

ws1

From the next screenshot you can see that the message is them broadcast out to the other client currently connected to the socket, in this case in Chrome.

ws2

Cors security

The cors security only allows POSTing from the copper.xomino.com site. This is a good thing :)

ws3

Conclusion

In this article we have seen how we can “create” a websockets emission event on the server by POSTing a message to a separate page within the application.

While this may seem pointless (“because why couldn’t I just create a normal websockets message from the page”), what we will see in a future article is the need to emit an event from the server which is not connected to the Websocket and doesn’t need to be.

 

6 thoughts on “XPages and Bluemix: How to create a Websockets message without being connected to the application

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s