Pages

Sunday, March 11, 2012

ColdFusion WebSocket Part4:Restricting Right to Publish


The very first and easy step to setup WebSocket is to use the default Channel Listener as I described in my first blog entry. But if you need to implement business logic to control the WebSocket system in your application you will have to use a custom Channel Listener CFC. Channel Listener has six methods which can be used to control who will publish/receive data as well as how to present data to different users.
In this blog I am explaining about how to control who all can publish data.
Consider the case of a forum. You have three types of users-Moderators, Members and Guests. Mostly you don't want guests to publish messages.
Let’s try to implement this restriction in your WebSocket Application.
You need a custom Channel Listener CFC. So let’s specify that in your Application.cfc



component
{
 this.name="forumapp";
 this.wschannels=[{name="forum",cfclistener="forumListener"}];
        
}

In a real-life application you might associate the type of user based on the credentials given during authentication. Here in my index.cfm, I am specifying the membership type of the user as a custom option while subscribing to the channel(See highlighted code).

<script type="text/javascript">
 function mymessagehandler( msgobj)
 {
  var message = ColdFusion.JSON.encode(msgobj);

  if(msgobj.data!= null)
   message=msgobj.data;
  else
  switch(msgobj.reqType)
  {
   case "welcome":
      message="Socket Connection established";
      break;
    case "subscribe" :
     message ="Subscription successful";
      document.getElementById("subscribeme").disabled=true;
      break;
       case "publish" :
     message ="Message Published";
      break;
   }
     var txt=document.getElementById("myDiv");
     txt.innerHTML +=message  +"<br>";
 }
 
 function publishmessage()
 {
  var msg = document.getElementById("message").value;
  mycfwebsocketobject.publish("forum",msg );
 }
 
 function subscribe()
 {
  
   var usertype= document.getElementById("usertype").value;
   // Type of user is Guest/Moderator/Member as user chooses in the form
   mycfwebsocketobject.subscribe("forum",{utype:usertype});
 }
 
 function myerrhndler(errobj)
 {
  var message=ColdFusion.JSON.encode(errobj);
  switch(errobj.reqType)
  {
   case "welcome":
      message="Socket Connection not established";
       break;
    case "subscribe" :
     message ="Subscription Failed";
      break;
       case "publish" :
     message ="Publish Failed";
      break;
   }
     var txt=document.getElementById("myDiv");
     txt.innerHTML +=message  +"<br>";
 }

</script>

<cfwebsocket name="mycfwebsocketobject"onmessage="mymessagehandler" onerror="myerrhndler">

<cfform >
Status:  <select id= "usertype">
 <option value="Guest">Guest</option>
 <option value="Moderator">Moderator</option>
 <option value="Member">Member</option>
</select>
<input id="subscribeme" type="button" value="Connect ME to Forum" onclick="subscribe();"><br>
  
Message: <input id ="message" type="text" >
 <input type="button" onclick="publishmessage();" value="Publish Message">
 
</cfform>
<cfdiv id="myDiv"></cfdiv>

We have specified forumListener as the name of ChannelListnter for the channel forum in our Application.cfc Let’s try  to implement the logic to restrict the right to publish in the forumListener.CFC. Here we are overriding two methods- allowSubscribe,allowPublish of the default Channel Listener to implement this restriction
component extends="CFIDE.websocket.ChannelListener"
{
  public boolean function allowSubscribe(Struct subscriberInfo)
   {
     if(structKeyExists(subscriberInfo,"utype"))
       {
        //Validating if a user has publish right & adding a new key to ConnectionInfo 
          if(subscriberInfo.utype eq "Moderator" or subscriberInfo.utype eq "Member" )
         subscriberInfo.connectioninfo.havepublishright="true";
       return true;
       }
   
    return false;
   }
  
   public boolean function allowPublish(Struct publisherInfo)
   {
       if(structKeyExists(publisherInfo.connectioninfo,"havepublishright"))
         if(publisherInfo.connectioninfo.havepublishright)
            return true;
    return false;
   }
 
}

You can download this complete example from here

We have implemented these functions keeping in my mind many application scenarios. If you are stuck at some point as to how to implement particular business logic, it would be worth a look at the ChannelListener functions. In the next blog I will try to explain more on the usage of different Channel Listener functions

For more reference and code samples on ColdFusion WebSocket see the previous entries in this ColdFusion WebSocket blog series



4 comments:

  1. your blog was too good. i really appreciate with your blog.Thanks for sharing.


    PU Document Cases

    ReplyDelete
  2. Your blog was helpful but do you know of a way to use the websockets to do one on one chats much like the Live Chat help that allows you to chat with a support agent. The chat will only go to the user and the agent and not broadcasted to anyone else. Their chat session will be isolated from however many other user/agent chat sessions there are. I'm sure you wouldn't create individual channels for each time a user wants to talk to any support agent. I've searched online but all of them show the multi-user chat and not a private chat. Example code will be really useful.

    ReplyDelete
    Replies
    1. As for communicating only to one client and not many, that is indeed covered in the CF documentation. But rather than try to figure it out from the CFML Reference (which would be like learning from a dictionary), see instead the Developing ColdFusion Applications manual. It has 50+ page chapter on using CF websockets, and it has a specific section on this point-to-point communication you seek:

      https://helpx.adobe.com/coldfusion/developing-applications/coldfusion-and-html-5/using-coldfusion-websocket/using-websocket-in-point-to-point-communication.html

      Delete
  3. The links at the bottom to her first 3 parts go to a domain that is no longer hers: http://www.eveysijo.com

    In case she may not see and correct this, the correct URLs for the 3 parts are:

    http://eveysijo.blogspot.com/2012/02/coldfusion-websocket-for-absolute.html

    http://eveysijo.blogspot.com/2012/02/coldfusion-websocket-part2how-do-i.html

    http://eveysijo.blogspot.com/2012/02/coldfusion-websocket-part3-interpreting.html

    ReplyDelete