XPages and Bluemix: Sending a targeted Websockets message to specific XPages

In this article I will demonstrate how the use of socket.io “rooms” enables us to send message to users who are only accessing specific pages within our application, rather than blanket messages to all users.

Introduction

In the previous article I demonstrated how to use a message POST to the node.js server which could then be turned into a chat message and sent out to all users. While this is a nice example it only serves as such and does not have significant business value. In this article I will begin the peel back the potential for much greater application flexibility through the controlled use of targeted Websockets messages to users of an application.

Most applications have more than one “page” within it and we may wish to send a message to users of one page rather than all pages. Conversely we may want to only send messages to users who are viewing certain types of information wherever they are within the application.

In this article we are still going to use the chat example but this will be the last time we use “chat” as the use case. In future articles I will look into more practical applications of Websockets messaging within an application.

Using rooms within socket.io

Looking at the socket.io documentation for rooms and namespaces you can see that the API exposes the ability to create individual communication channels between the server and the application users.

How this translates to our application on the node.js server looks like this:

  socket.on('joinRoom', function(room, name){
    socket.join(room);
    io.sockets.in(room).emit('notice', name+" has joined");
    console.log(name+" has joined room "+room)
  })

When the “joinRoom” event is registered on the server then the socket is joined to the room name which is passed in. A message is the broadcast specifically out to all the existing room members that the new user has joined. Note that this message is room specific because of the io.sockets.in(room) rather than a blanket message to all users.

With this code in place on any page we can register our application page (chat room in this case) with the socket server. In my case I created a generic function to take the name of the “room” from the XPage URL. The following client side JavaScript sends the “joinRoom” request to the server.

  nickname=$('.username').text()
  // Send message to server that user has joined WinX.nsf/xRoom1.xsp?open&login
  var xpageName = location.href.split('.nsf/')[1] //xRoom1.xsp?open&login
  xpageName = xpageName.split('.xsp')[0] //xRoom1
  socket.emit('joinRoom', xpageName, nickname);

On the server we can then see the console.log as someone joins the room:

s1
We can then have multiple users in individual “rooms” which are in this case 3 separate xPages xRoom1.xsp, xRoom2.xsp, xRoom3.xsp From the original chat room I am able to sen all three rooms a blanket message because they are all “listening” for “msg” as in the previous articles

 socket.on('msg', function(data) {
    console.log('msg here')
    console.log(data)
    redisClient.lpush('messages', JSON.stringify(data));
    redisClient.ltrim('messages', 0, 99);
    socket.broadcast.emit('msg', data);        //broadcast to all users indiscriminately
  });

s2

Sending a message to a specific room

Modifying the original POST code which was shown in the previous article I was then able to create an XPage which will send a targetted message to a specific room. To do this, all I had to do was pass in an additional POST parameter of the room I wanted to send a message to.

I create a new Master XPage which had 3 fields on it – one for each room. Each of the individual fields had a “room” attribute which allows me to pick up a value to specify which room to send it to.

<div id="msgRoom1" class="msgCenter">
	<input placeholder="Send a message to Room1" room="xRoom1" autocomplete="off" autofocus="autofocus" />
	<button type="button">Send</button>
</div>
<br/><br/>
<div id="msgRoom2" class="msgCenter">
	<input placeholder="Send a message to Room2"  room="xRoom2" autocomplete="off"  />
	<button type="button">Send</button>
</div>
<br/><br/>
<div id="msgRoom3" class="msgCenter">
	<input placeholder="Send a message to Room3"  room="xRoom3" autocomplete="off" />
	<button type="button">Send</button>
</div>

s3

In the following code we bind to each of the buttons so that when the are clicked they:

  • set msgField to be the jQuery object representing the pertinent field
  • create the data object to send to the socket server
  • create the newMessage passing in data

The new message function then:

  • POSTs the data object at the “/roomPost” path on the server
  var socketServerURL = (location.href.indexOf('copper.xomino.com')>0) ? "http://copper.xomino.com:3000" : 'http://xominosocket.mybluemix.net'
  var socket = io.connect(socketServerURL)

$('.msgCenter Button').on('click', function(){
  	var msgField = $(this).prev('INPUT')
	var data = { text: msgField.val(), nickname: nickname, when: new Date(), room: msgField.attr("room") };
	sendMessageToRoom(data)
	newMessage(data);
	// Clear the message field
	msgField.val('');
})

var sendMessageToRoom = function(data){
	console.log(data)
	$.ajax({ url:
	        socketServerURL+"/roomPost",
		type: "POST",
		data: data
	}).done(function( msg ) {
		console.log( msg);
	});
}

We can see the message come through on the server

s4

You can also see from the log that I was able to join 3 rooms from the Message Center page – this is as simple as creating three requests to join:

  //client side JavaScript
  socket.emit('joinRoom', 'xRoom1', nickname);
  socket.emit('joinRoom', 'xRoom2', nickname);
  socket.emit('joinRoom', 'xRoom3', nickname);

Site in action
The best way to see all this is to see it in action – as you can see from the video below.

Moving the application to Bluemix

Working locally I used to following code to determine if I was on copper.xomino.com or another server (demo.xomino.com or different again)

  var socketServerURL = (location.href.indexOf('copper.xomino.com')>0) ? "http://copper.xomino.com:3000" : 'http://xominosocket.mybluemix.net'
  var socket = io.connect(socketServerURL)

I had to make a slight change to my cors code in the local node server setup. I looked at the cors npm site to see how to dynamically add cors support and found the answer and modified my code accordingly. So you need to make sure you

//Marky adding CORS from copper
//app.use(cors()); //not used for whitelists

var whitelist = ['http://copper.xomino.com', 'http://demo.xomino.com', 'http://marky.psclistens.com'];
var corsOptions = {
  origin: function(origin, callback){
    var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
    callback(null, originIsWhitelisted);
  }
};

marky.psclistens.com is the same local server as copper.xomino.com (I use a hosts file to make them both look at localhost). But this allows me to play with cors and in this case talk to the local or bluemix node server without needing another “Domino” server.

s6

Because the site running locally is already connected to the Jazz Hub Git repository, as with the previous examples all I have to do is commit the changes locally, push to the Jazz Hub repository, the application will then be re-built and re-deployed to Bluemix.

It’s really about as simple as that. Because the code is already primed to check to see if we are looking locally or at Bluemix, a new URL for the application now looks at Bluemix.

s5

 

So why do we need Bluemix again?

While the development was performed locally, the intention is to be able to create a capability which does not require the user to have a locally running node.js server. That is where Bluemix comes in. In essence what we are creating is a cloud hosted Websockets service which can be integrated into existing applications.

 

Conclusion

In this article we have seen that with a little creativity we are able to register different chat rooms within the same application. There are other ways to do this of course but the point of this example was to demonstrate the ability to send a specific message to specific users looking at an individual XPage.

In the next article we will take a look at the practical implications of this within an XPages application.

 

Advertisements

Because developers make mistakes – Webstorm Local History

Similar to Eclipse, Webstorm has a local history capability, allowing the developer who realizes they made an idiot mistake an hour ago, to go back to it and save their day.

We’ve all been there and while committing to source control is a must for modern development, there are those times in between commits and then those when you are just too lazy to go through the repo looking for it.

Local History

Local History is always enabled in Webstorm – for the official help check here.

Under the VCS Menu you will find Local History. Open the file you want to view the history form and then

a1

This will then show you not only the local history between saves – but also the Source Control Commits – sweeeet !

 

a2

You can then copy back the changes, revert and or play with the changes you have made as they are highlighted between the current version and the selected old one

a3

a4

Create your own Watson Q and A example with Bluemix, Webstorm and Jazz Hub

Introduction

In this article I will demonstrate how to get up and running with one of the Bluemix/Watson service examples. I will be using the example provided by IBM in their documentation as the basis for the article but the way in which I achieved the final goal was quite different from the way that they explained it in the example.

This example will use:

I could have added BS words as an attention seeking headline, and it would fit because there is so much I want to show in this one post (it is probably should be 5 separate posts). But I figured that it’s probably better to have a more description title about what this is really about (more googlable that way). So be warned this is a longer post than normal because of all the pictures. Going through this experience helped me better understand Git, Webstorm (and how it uses Git), Jazz Hub and Bluemix.

Creating an example of using the Bluemix Watson service.

Earlier this week IBM announced that they added the Watson API as a service to Bluemix. I honestly have no idea what I would ever use this for in my line of business but the coolness factor is huge!

In this post I am going to demonstrate how I was able to create the example service without using the same process as laid out in the IBM documented example. As this is a long post (lots of pictures) I will be discussing the separate parts in other posts.

There are also other ways of creating your App from scratch (for example Create an App, select node.js as a runtime and then bind the Watson service.) The reason I did the example this way was to highlight that you do not always have to start with a new service. I needed a node.js runtime, and it happened that one of my services already provided that (the DataCache starter service). That’s kinda cool and kinda the point of Bluemix!

1) Log into Bluemix

https://ace.ng.bluemix.net

Your should be presented with your dashboard.

2) Create an App 

 

 

a1

 

Select the Node.js runtime
w1

 

Name the App (in my case the App is called xominoWatsonQandA and the Host is xominoWatsonQ)

w2

3) Add a service – Watson Question and Answer 

w3

w3

4) Assign meta-data to the new service

  • Give the service a name – you will need this later so don’t over complicate this (qa-service)
  • The Watson service is currently in Bluemix as a Beta at time of writing

w4


5) Confirm you have an application

Now we have the pieces necessary to build the application on.

  1. A Node server
  2. The Watson service.

w5

6) Make sure you have a Jazz Hub account

If you do not already have a Jazz Hub account then go and create one here https://hub.jazz.net/

NOTE: The Jazz Hub site uses your IBM login userid and your Jazz Hub password – do yourself a HUGE favor and make the password the same as your IBM account and if you ever change the password on your IBM account you have been warned 🙂

Here is a shot of my Jazz Hub account before we start – note no “xominoWatsonQandA”

w1

7) Add your new application to Jazz Hub

Select the “Add GIT” option on the top right of your App dashboard

w6

8) Confirm existing service code?

The next prompt asks me if I want to create starter code in the new Git Source Control repository. In this case I do not – un-check it.

w9

9) Go to your new source control Git repository

Click on the Jazz Hub URL displayed on the right hand side.

The Add Git link will be replaced with a link to the repository. Click on the link to go to there. We will look at Edit Code in another post.

 

w7

 

10) Get the URL of the repository

In the picture below you can see over on the right there is a link for the Git URL – click on that and copy the URL.

w11

11) Open Webstorm IDE

As I was working my way through this example I wanted to learn more about how Webstorm functions as a Git client. You can use Source Tree or the Git command line if you prefer.

You need to ensure that Git is enabled in Webstorm before you proceed. it is not configured out of the box. The instructions for enabling git are found here https://www.jetbrains.com/webstorm/webhelp/using-git-integration.html. You will need to have Git installed before hand. Follow the ssh key instructions and it will show you how.

12) Checkout the new repository

Select Checkout from Version Control > Git form the Webstorm VCS menu option

w12

 

Paste the URL from the Jazz Hub site into the Vcs Repository URL

w13

Select Clone and a new project is created within Webstorm and as you can see, the files downloaded are those from the repository on Jazz Hub

w14

12) Download the example code and add to the local repository

Following the example site, download the sample file qa-nodejs-sample.zip. Unzip it locally and drag the files into the repository directory created by Webstorm in the previous step.

w15

Clicking back into Webstorm you will see the files refresh in the project – they all appear “red” because although the files are in the repository directory they are not current added to the Git configuration, it does not know they exist.

w16

13) Add the files to the local Git repository

Right click on the project and add the directory as follows.

w17

The files will all turn green

14) Edit the manifest.yml file

Within Bluemix the manifest,yml file is the key to holding everything together. It contains the “services” and the application they are used in. In my case the service name for Watson was qa-service and the application is xominoWatsonQandA.

Save the Manifest file

w8

You can also see from the manifest file command “node app.js“. If you look into the other files currently in the example you will find app.js. This tells Bluemix how to start the application.

15) Commit the files to the local repository

Right click on the project name – select Git > Commit Directory

In this case I chose to Commit and Push back to the repository

 

w20

w21

Webstorm then does a stupidity check on your files (we all need that)

w22

And then Webstorm tells you that you are stupid!!

w23

On dear……….well actually if you look into this, Webstorm is reporting issues in the example app css files and missing semi-colons in the JavaScript. Without going into correcting all of them, the application works despite these errors. So we Commit and continue.

w24

My commit comments are “Modified manifest and all files”

Pushing…

w25

We get confirmation that the files were committed and pushed up to the Jazz Hub repository

16) Confirm Jazz Hub

You can now see by refreshing your Jazz Hub page that all the files are now in the server repository. You can also see next to my picture in the middle “Manifest change and all files” as the last commit comment.

w26

Then comes the really cool and completely not Command Line experience. In the top right of the page you can see Build and Deploy….

17) Build and Deploy

w27

18) Confirm

You will be taken to a page where you can see the results of the build and deploy. Jazz Hub is very smart and self aware. If you have un-committed changes within your repository it will not let you Deploy. That is for another day though.

w28

 

Note: what’s interesting is that the Deploy to URL which I cannot change is xominoWatsonQandA.mybluemix.net not what I would expect as xominoWatsonQ.mybluemix.net which is the route I gave the application in the first place. Turns out I not have two routes to the same App. I can see this back on my bluemix dashboard as there is now a (+1) next to my routes options!

So note to self, name your route the same as the application name!

w10

19) You now own Watson

Click on the route link back on your Bluemix dashboard and you now have a running example of the Watson Heathcare service

w9

In review

In this example we saw a LOT of cool new features, concepts and ideas for Domino developers and you know that we have barely scratched the Bluemix, Webstorm, Jazz Hub surface. I learned a significant amount of new and cool things from going through this process. The first time from scratch it took about 90 minutes to figure out what I was doing. The second time I went through it, even taking all the screenshots for the blog it took 25 minutes.

We only changed two lines in one file to make this work – anyone can do this !!

Like I said at the top of the article, I have no idea how I would use Watson in the day job but that was not the purpose for doing this example. These “services” are componentized capabilities which we can take advantage of. Imagine the growth possibilities as more and more services are added to Bluemix. This has got to be fun to watch and follow along. Remember IBM are investigating putting Domino into Bluemix.

The Watson Cloud REST API information is available here http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/apis/#!/Question_Answer

This is so cool 🙂

Angular.js in XPages #1 – Using the right IDE for development

In this article we will look at Webstorm (a Javascript IDE) and discuss how that relates to the traditional XPages development environment.

Tools

Better Tools make better applications (or something like that). It’s true to an extent, you can’t help a poor developer make a great application but with better tools you can make a good developer more productive, which ultimately makes for a better application (probably). In the XPages development world the tooling we have is all based around Domino Designer in Eclipse (DDE). Eclipse as we all know is an open source tool which while originally designed for Java development has been extended to cover development of many programming languages. There are XML editors, JavaScript editors and many others. In the XPages world we are also “stuck” with quite an old version of Eclipse and are unable to take advantages of newer capabilities and plugins for modern eclipse development. DDE “works” but it is far from a fantastic experience, especially from a “web development” perspective. In these articles I will not be using DDE very much at all. We are going to look at Web Development using Domino Data, not doing web development using Domino.

I am no expert on Java development using DDE but from what I have picked up there are others who are doing their pure java development outside of DDE and then importing it into DDE to run in their applications. For power-developers stability and speed are just as critical as flexibility and practicality.

Web development environments

There are a number of tools currently en vogue for web developers. SublimeText is a very powerful text editor and Github have release a new “Atom” editor which is getting a lot of press right now as well. I am going to use JetBrains Webstorm for these articles. Webstorm is a great IDE and comes with a bonus of having Angular integration built in.

Webstorm

Webstorm is not a free tool – you have to buy a copy – but IMHO it is worth it. $50 for a personal license is about 1/2 hour of your productivity and it will pay for itself inside of a few days. There is a 30 day evaluation period which I encourage you to try 🙂

For a full list of examples check out the demo page – http://www.jetbrains.com/webstorm/documentation/ but here are some of the cool examples:

  • Angular integration into HTML ws2
  • Type ahead JS ws3
  • Type Ahead CSS ws1
  • Code formatting
  • Keyboard shortcuts (TOTALLY AWESOME) – https://www.youtube.com/watch?v=PNZJox8pkls
  • Debugging and live text editing using a Chrome extension

Why not use DDE and XPages?

Well first and foremost because an “XPages” is an XML document and because of that, DDE requires it to be written using correctly formed XML. HTML is not correctly formed XML and causes issues. Let me demonstrate: If I want to create the following HTML inside of DDE I get an error:

<div enter exit>

</div>

ws4 Seems simple enough but we really should use the right tool for the right job.

This is particularly important when we start to look at Angular directives which rely (when not using the HTML5 standards) on the single word attribute in the HTML element.

Secondly, as you will see from the examples in the upcoming articles I will be creating HTML pages not XSP pages. These can still reside inside of the database but are not “XPages”. I will not be using XPages “controls” and in fact not using Dojo either. So there is no benefit to using DDE at all in this case for my front end development. I will be using DDE to create REST services (maybe) and I would use DDE to create Java code to supply data to the user.

Finally –  Eclipse is a large tool and is frankly slower than me. It’s a frustrating when I constantly have to find something to do while a database waits to open, checks mail, Builds something, crashes in a corner quietly. I won’t miss using it.

Working locally

Even if we are not working with a Domino server, we still need to be able to review and test what we are working on.

In Webstorm you can preview your code as Webstorm generates it’s own local basic web server. The web server is configurable and as we will come to see it will help us in our Domino development environment as well.

ws10 ws11

 

Debugging

Webstorm has an internal debugger (similar to chrome dev tools and firebug) and you can debug the code with the JetBrains Chrome extension

ws1

One really nice feature about the debugger is that it allows Live editing, so you can edit and build you code and watch in real time as the code is updated on the screen. This is very cool when you are building out your HTML templates. I this case on a large monitor I have the IDE on the left and the browser on the right. You can see this technique in action on the http://egghead.io angular tutorials.

ws2

Starting to type into the debugger window you see the HTML updated on the right – Angular does not update the {{phone snippet}} because the template has to be redrawn. HTML on the other hand is redrawn immediately

ws3

Hitting F5 refresh in the browser reloads the template without having to save the HTML on the left

ws4

As we will come to see this will allow us to take data from Domino without worrying about CORS issues. For more on the debugger read here – http://www.jetbrains.com/webstorm/webhelp/using-jetbrains-chrome-extension.html

As we get more into the demonstrations we will look at getting data from the notes database and how that works practically on a localhost

In the next we will look at a basic overview of some Angular concepts – in the mean time check out the developer tutorials

Conclusion

Even in the short time I have been using Webstorm I have found it to be an exceptionally quick development environment compared to DDE. DDE certainly has its place but even if I am not using angular for future projects I am seriously going to consider doing as much of my development using Webstorm rather than DDE.

Tooling is a very personal thing for a developer, in this case when I am approaching the project from a Web Development perspective and creating web pages without the overhead of the JSF lifecycle, there really is no need to use DDE to build these examples. I am going to use XPages for data sourcing and CRUD.

*Disclaimer*

I do not want this to become a discussion of whether this approach or not this is right or wrong and I encourage everyone to consider their comments before posting. The point of this series is for education and mind broadening, driven by my own selfish desire to learn and broaden my mind.

  • Yes there are many great things I am giving up by not using DDE and XPages controls
  • But I am also going to gain a lot of things which XPages does not allow me to do easily or gracefully

*/Disclaimer*

 

PS

Just so you know Jetbrains also make a Java IDE which is used for android development – http://www.jetbrains.com/idea/ – another alternate to eclipse. Again it isn’t free, but may be worth checking out because free doesn’t mean the best (and visa versa).