Pages

Tuesday, February 28, 2012

ColdFusion WebSocket Part3: Interpreting response

In the previous blog, we discussed how to publish messages. Here, let me explain how to interpret ColdFusion WebSocket responses.

Most of the ColdFusion WebSocket responses are asynchronous, which essentially means that  the response to your WebSocket method calls (such as getSubscriberCount, getSubscriptions, publish, invokeAndPublish, or invoke) come to message handler.
Look at the sample snippet:
var cnt= mywsobj.getSubscriberCount(channelname);
Here, if you expect to get the value of number of subscribers on the channel in the variable "cnt", you are wrong. The response to this WebSocket call comes to your message handler and you have to extract data from there.
Since there are different types of responses and all of them come to the message handler. The application developer has to interpret each response, figure out the operation that triggered, and show the response appropriately.
Let us now try to crack the responses received.
In the examples given in my previous blog post, I used ColdFusion.JSON.encode inside message handler to convert the JavaScript object to a string so that you can see all keys and values of the messageobject.Here we are going to categorize the responses received.
Firstly, let us divide the messages that come to your WebSocket object in two ways depending on the value of code key.
  • If code key is a 0 , it's a successful message.
  • If the code key is -1 or 4001, it's a failure message.
All responses with code 0 will come to the message handler. If you have specified an error handler, all responses with code -1 and 4001 go to the error handler. If  error handler is not specified, all responses go to the message handler.

In the example, we have both message handler and error handler. You can use this code in the message handler. Here messageobj is the argument of message handler function.

if(messageobj.type == "data")
      message=messageobj.data;
else
if (messageobj.type == "response") {
switch(messageobj.reqType)
{
case 'welcome' : 
message="Websocket connection Established";
        break;

case "subscribe" : 
message="Subscription successfull";
        break;

   case "getSubscriberCount" : 
message="No:of subscribers= " + messageobj.subscriberCount;
        break;

   case "getSubscriptions" : 
       if (messageobj.channels.length >= 1) {
message=" You have subscribed to "
for (var j = 0; j < messageobj.channels.length; j++)
{
if(j>0) message +=", ";
message +=   messageobj.channels[j].id;
}
}else message ="You have not subscribed to any channels"
       break;

   case "publish":
       message="Message successfully published";
break;

   case "invokeAndPublish":
       message="Method invoked and message successfully published";
break;

   case "invoke":
        message="Method invoked <br />" ;
message=messageobj.data +"<br />";
break;

   default: message = ColdFusion.JSON.encode(messageobj);
break;
}
}

In the code, I have just customized the message that needs to be displayed for each kind of response.
Instead, you can call different JavaScript functions to update your UI controls with appropriate data.
Also, you can use similar code in error handler to handle error situations.
Download this basic code sample which you can use to perform almost all  WebSocket operations. It also displays customized message for each response.

Hope you are more and more convinced that ColdFusion WebSocket is easy and effective. I will try to post some advanced concepts in the next few blogs.




Wednesday, February 22, 2012

ColdFusion WebSocket Part2:How do I publish Messages?

One major advantage of using ColdFusion WebSocket  is that it enables you to send data to multiple clients at one go.That is, the server can publish message to multiple clients and each client can publish message to multiple clients.
So lets get familiar with the different ways to publish data.

  • Publish from server: If you want to do a publish from ColdFusion server you need a CFML function, and that function is wsPublish.
  • Publish from Client:When a client wants to publish a data, you need a JavaScript function.This can either be publish or invokeAndPublish methods associated with a ColdFusion WebSocket object.


Using ColdFusion Function:
Here is a sample code to publish a simple message from Server to the channel -publishdemochannel.
Wspublish("publishdemochannel","Welcome to publishdemochannel");
Instead of the simple message you can also publish different types of data, like array, struct and query using wspublish.

Using JavaScript Methods:
ColdFusion WebSocket object has got two methods- publish and invokeAndPublish which can be used to publish message from client side. If you are using a simple JavaScript publish, you should have the message that needs to be published. You can use  invokeAndPublish, if you have a function defined  in your cfc which will be able to provide the message that needs to be published.

JavaScript  publish:
Once you have created your JavaScript websocket object using cfwebsocket tag you can invoke Javascript publish method to publish a messages over channel/subchannel.
This can be done in your JavaScript code block For example,
mycfwebsocketobject.publish("publishdemochannel","My test message to publishdemochannel" );

Here we are publishing a simple String. You can also pass a string variable,a javascript array or even javascript object as argument to the publish method.
For example you could publish an array to a channel like below inside a JavaScript code block.

mycfwebsocketobject.publish("publishdemochannel",["Jan","Feb"] );

or you can use a Javascript array variable like below
var myarr= new Array();
myarr[1]="Jan";
myarr[2]="Feb";
myarr[3]="Mar";
mycfwebsocketobject.publish("publishdemochannel",myarr);


You can also publish a JavaScript object using the publish method.
var myobj= new Object();
myobj.fname="Evelin";
myobj.lname="Varghese";
myobj.age=28;
myobj.gender="Female";
mycfwebsocketobject.publish("publishdemochannel",myobj);


Using invokeAndPublish:
As I mentioned earlier invokeAndPublish is used to call a CFC function.The value returned by the function is published over the channel.
For example you have the employee id of the person, but you don't have the name of the person, you can use invokeAndPublish method of websocket to invoke the cfc method that will take the empid and will return the  message that needs to be published.
mycfwebsocketobject.invokeAndPublish("publishdemochannel", "employee",      "processMessage",[389,"Hello "]);
The value that the fucntion returns will be published to the channel specified:
component
{
public function processMessage(eid,msg)
{
            //Write your logic to get the empname based on empid
    var empname="Evelin";
    return msg & " " & empname;
}
}

Download this code sample which publishes different types of messages.

With the description here I hope you will be able to get started with your application to manage real time data. In the next few blogs I will try to explain more scenarios that you will come across in your ColdFusion WebSocket  application  development.
For more on How to handle responses from server checkout my next blog entry 

Saturday, February 18, 2012

ColdFusion WebSocket Part1:Getting Started

ColdFusion Websockets?What can I do with it?
                 You can write real-time Web applications and handle data with high efficiency but less complexity. Consider the case of a simple collaboration app that you use to chat. It is a simple task to build it using ColdFusion WebSocket. Yes, you could have done this without WebSocket, but that demands complex architecture and some hacks. Likewise you can create  bidding apps, a stock ticker etc in very short amount of time with ColdFusion WebSockets.

But how is it different?
    I know, you are used to HTTP. WebSocket is different from normal HTTP request response way of communication. In simple terms, if you want any data from your app server you have to send an http request in the form of form submit or some page request,but with  WebSocket you can keep receiving data from the app server without any action. Yes, I mean no action. In fact, you can have a two-way communication between client and server without page reloads.

So how do I implement it?
     You need to have ColdFusion 10 to make use of WebSocket. If you have not  installed it yet, get it from here .
Here is a very simple websocket channel implementation with  minimal lines of code

Step1:  Specify the channelname in  Application.cfc file
            This is absolutely mandatory if you need to establish websocket channel communication.
So your simplest Application.cfc will have the below code.
component
{
   this.name="wsdemoapp";
   this.wschannels=[{name="stocks"}];
}
Note that the above code is in ColdFusion Script syntax. We have specfied the name of the websocket channel as stocks

Step2: Use the new cfwebsocket tag to establish connection from your cfm page to your channel

<cfwebsocket name="mycfwebsocketobject"  onmessage="mymessagehandler" subscribeto="stocks" >

Here we have given mycfwebsocketobject as the value for name attribute, which will create a reference to a javascript websocket object.What this implies is that you can use mycfwebsocketobject as a Javascript object inside javascript code .This object has certain methods associated with it which can be used to  perform various operations over websocket.

Also note that in the above code sample I have specified mymessagehandler as the value of onmessage attribute. mymessagehandler should be a Javascript method .This is the method that will recieve all communications over the channel.

Step3:Define the message handler
<script type="text/JavaScript">
   function mymessagehandler(messageobj)
    {
         //Converting the JS object to a string and display  in "myDiv"
           var message = ColdFusion.JSON.encode(messageobj);
           var txt=document.getElementById("myDiv");
           txt.innerHTML +=message  +"<br>";
 }

</script>
Don't forget include a div with id "myDiv"  in your cfm page to display the messages .

Step4:Run your cfm page.
If you see a string of below format in your cfm page the WebsSocket Connection is successful

{"clientid":41244233,"ns":"coldfusion.websocket.channels","reqType":"welcome","code":0,"type":"response","msg":"ok"}

You can write application specific logic in your message handler to display the messages coming over websockets  in appropriate way.You can download the example described here.

This example just establishes a connection of websocket .For more on how to transfer data, keep watching for more posts. In the next few blogs, I will explain more advanced scenarios.
Happy playing with ColdFusion 10!!!

For more on how to publish messages check out  ColdFusion WebSocket Part2: How do I publish Message?