In this article I will introduce and discuss the OpenNTF WebSockets OSGI plugin by Mark Ambler. The websocket plugin posted to Mark Ambler is based on the http://java-websocket.org/ project.
I realize I am not the first person to play with a websocket server on top of a domino database. I know of at least 4 other people who have at least done their own POC for this. But this is the first time I have got my hands on it 🙂 I’m a little excited……
Brief overview of WebSockets
I already wrote about the reasons for websockets in XPages. But to recap, WebSockets allows me the developer to PUSH messages out to logged in users without them asking for it. This reduces network traffic and creates a new paradigm for fluid data update.
What I will be doing over the next few blog posts is demonstrate examples of why WebSockets fundamentally changes how we architect our web apps in the future. Yes it is that significant in my mind.
How does the Domino integration work?
- Download the OpenNTF project, unzip and follow the instructions in the PDF file.
- Make sure you sign the update site before deploying
- Install the update site in Domino Designer and restart
- Understand that this is not port 80….this is demonstration right now and not production ready.
Once you have the plugin installed and up and running application you will be able to use the chat.nsf example to demonstrate for yourself what is going on. This is only intended to be an example of what is possible, not a production app. replacing sametime 🙂
From a Domino perspective, The core of the application is the websocket.nsf database. In there if you look at the Broadcast Example Agent you will see how it works.
This article was written based on code release 1.0.7
By creating a document in the database with the appropriate fields, the websocket OSGI code picks up the document from the view and routes it out to the users.
The websocket.nsf database tracks users in the vUsers view and from there we can ascertain the unique code assigned to each logged in user.
Using that websocketID listed in the view we are able to ensure that the appropriate message is transmitted to the appropriate user.
To extend this into something I can use I create an SSJS function which will look up the socketID – in this case I do not need to know the ID – just the username.
function createMessage(socketID, msgObj){ var db:NotesDatabase = session.getDatabase("","websocket.nsf",false); var doc:NotesDocument = db.createDocument() var online = "" if (!socketID){ var view = db.getView("vUsers") println("rec: "+msgObj.recipient) var user:NotesViewEntry = view.getEntryByKey(msgObj.recipient) if (user){ socketID = user.getColumnValues()[1] online = user.getColumnValues()[2] println(socketID) } } if (socketID && (online=="ONLINE")){ doc.replaceItemValue("Form", "fmSocketMessage") doc.replaceItemValue("from", msgObj.from) doc.replaceItemValue("to", socketID) doc.replaceItemValue("sentFlag", 0) //The msgObj will come in as an Array of Json - we need to convert that into a multi-value notes field //This is planned to be fixed to apss the JSON straight through in a later release for (var i=0; i<msgObj.data.length; i++){ var temp = msgObj.data[i] for (key in temp){ if (i<1){ var item:NotesItem = doc.replaceItemValue("data", key+"="+temp[key]) } else { item.appendToTextList(key+"="+temp[key]) } } } doc.replaceItemValue("text", "") doc.save() } else { println("WebSocket messgae not sent") } }
I can then call this function from an XPages button (or anywhere else for that matter) and pass in the data as an object.
<xp:button value="Send Message" id="button1"> <xp:eventHandler event="onclick" submit="true" refreshMode="complete"> <xp:this.action> <xp:executeScript> <xp:this.script><![CDATA[#{javascript: var msgObj = {} msgObj.recipient = context.getUser().getDistinguishedName() msgObj.from = "Marky demo" msgObj.data = [{"beer": "english"}, {"lager": "french"}] createMessage("", msgObj) }]]></xp:this.script> </xp:executeScript> </xp:this.action> </xp:eventHandler> </xp:button>
Looking at the chat example below which I have also slightly modified to console.dir the output so that it is readable we can see the message is sent to the client
In a more advanced demonstration I added a field to the right hand form so that i can pass through my own JSON – the video below shows this best 🙂
This was recorded at 1920 resolution so it appears blurred on youtube – CHANGE THE QUALITY to 720HD and that will fix it
OpenNTF WebSockets OSGI plugin
Caveat
Please bare in mind this is not production ready code – and it may never be……
Because there are two servers running (domino and websocket) the websockets are current running over a non-standard port. I believe IHS can be used as a proxy to fix that.
As a proof of concept though and to get the information out to the community and IBM (hint hint) this is a great step forward in capabilities.
This is a great example of using and OSGI plugin and the Java code in Domino to access a Java server and transmit data – very cool !
Conclusion
There is no polling of the server by the client. There are zero unnecessary http calls
We can have any application with an appropriate update, review the users who are logged in and update their web page with the appropriate data.
THIS IS AWESOME!!!!!!!!!!!!
Awesome!!!!!
Next – more examples
I feel a series coming on…….:)
Update
You know a project is moving along when this blog post was already out of date by the time I am ready to post it – but rather than waste it because there is good information in here – here’s the disclaimer.
This post is based on v1.0.7 of the webshell code release – as of v1.0.8 the JSON data is being passed via rich text which allows for pre-formatting server-side before sending it out. This also allows for more complex JSON creation than multi-value text fields can handle – thanks Mark – more about that soon !!
This change was based on my request for a feature on the github site
If you want to see this improve and progress – get involve – play with the code and make requests for changes – like everything OpenNTF – the more you play with it and the more people are involved – the better it will become !