Using iKnowBase Instant

Concept

iKnowBase comes with client and server side support for creating applications with real time asynchronous messaging.

Features of iKnowBase Instant:

The key feature with iKnowBase Instant is that a web client will get notified as soon as a message matching the subscription is available. The message may be whatever the applications use the message topic for (new document added, document updated, user has logged on to instant, “Hi! How are you?”, ...). This enables the type of rich interaction possibilities for web applications that has previously only been available in traditional non-web applications.

JavaScript API and transport mechanisms

The JavaScript API supports publishing and consuming messages in real time and is the primary API available for iKnowBase Instant. The API and corresponding server side support in the Instant Server is based on the Atmosphere Framework .

The Instant Server supports multiple asynchronous transport mechanisms, discussed in the following chapters.

Synchronous HTTP

Traditional synchronous HTTP transport follows the following pattern:

  1. Client sends a HTTP request to the server and waits for completion.
  2. The server generates a HTTP response and replies to the client.
    1. The client receives the HTTP response and has completed the message exchange. The network connection is closed or, if HTTP KeepAlive is in use, kept open for a period of time for subsequent requests.

The client will not get notified if an event occurs after the message exchange has completed. The client needs to send a new request if it wants new content.

Ajax (Asynchronous JavaScript and XML) techniques can be used by the client to make the application behave in a rich asynchronous way, but the the client still needs to poll the server for new content.

Asynchronous HTTP

Asynchronous HTTP transport is preferred for applications where you want to maintain a dialog between client and server or where the server facilitates a dialog between clients.

Asynchronous HTTP transport follows the following pattern:

  1. Client subscribes to messages from the server and has callback functions in place in case an event occurs.
    1. Control is immediately returned to the client.
  2. An event is detected by the server and is sent to the client.
    1. The client processes the event in the relevant callback function.
  3. Another event is detected by the server and is sent to the client.
    1. The client processes the event in the relevant callback function.
  4. The client sends a message to the server.
    1. The server processes the message
  5. ...

The client will get notified as soon as an event occurs.

While the client still uses Ajax (Asynchronous JavaScript and XML) techniques for subscribing and processing messages, the events are sent to the client as soon as they are available.

long-polling

The long-polling technique, also knowns as Comet, is a variant of the traditional HTTP request polling where the server waits until a message is available or timeout occurs before returning the response. The client will immediately re-connect and have a connection available for more messages.

long-polling is supported by all web browsers and is the default transport mechanism configured in the Instant JavaScript client library.

websocket

Websocket provides a bi-directional communication channel over a single TCP connection. It uses HTTP for handshake only and then upgrades to websocket protocol. Both client and server may push messages using the established communication channel without reestablishing the channel between messages.

The use of websocket will significantly improve performance when sending and receiving messages as all messages in a conversation is sent/received using the same connection. The overhead of the HTTP protocol is also not added to every message, reducing the amount of network traffic. Although more performant, the protocol is currently not as widely supported as long-polling.

Websocket with iKnowBase Instant is currently supported on the following browsers:

Web browser Minimum version
Chrome 13
Firefox 9
Internet Explorer 10
Opera 11
Safari 5
Safari (iOS) 5
Application Server Minimum version Comment
iKnowBase QuickStart 6.3 The first release including iKnowBase Instant
GlassFish 4.0 Includes JSR-356 Websockets support

Websocket with iKnowBase Instant is NOT supported on the following application servers:

Application server Version Comment
GlassFish 3.1.2.2 NOT supported.
WebLogic 12.1.1.0.2 NOT supported.
WebLogic 12.1.2.0.0 NOT supported. Has JSR-356 Websockets support, but will not work due to special URL requirements for websockets which disqualifies use in iKnowBase Instant.

Note#1: The protocol must also be supported by all intermediate middleware servers between the client and application server, such as load balancers, caches and front web servers. Take care to examine your web clients and middleware infrastructure for protocol and supported number of connections to see if you can use websocket.
Note#2: It is possible to deploy the Instant Server server separate from the other iKnowBase application when using a load balancer or when Cross Origin Resource Sharing (CORS) is enabled. This brings websocket availability to otherwise unsupported middleware infrastructure.

Transport failover

The JavaScript API offers an option “fallbackTransport” for configuring transport to use in case the primary transport fails. fallbackTransport defaults to long-polling.

Example:
Transport: websocket
FallbackTransport: long-polling

Note#1: Some intermediate servers may hog or drop connections that use an unsupported transport instead of rejecting them. This may prevent the client from using fallbackTransport within an acceptable period of time.

Blocking and non-blocking I/O

Web and application servers have traditionally used a blocking I/O model when handling web requests. The server thread processing the request will be occupied until the response has been delivered. Supporting a large amount of asynchronous clients who are “always connected” would relatively quickly use all available server threads and block the server for incoming requests.

Servers supporting non-blocking I/O will queue the request as soon as it is received and free the request acceptor thread for new requests. The request itself is further processed/used at some later time by the server. This allows for a huge amount of simultaneous connected clients compared to blocking I/O.

Servers, both application and intermediate servers, participating in the asynchronous support (for JS API clients) in iKnowBase Instant should always use non-blocking I/O.

Topics

A topic is an area where clients exchange messages. A client can only subscribe to one topic per connection, but the client can use multiple connection if needed.

The topic identifier is composed of:

Two topics with same name and different topic options are two different topics.

See Topic name and topic options in the iKnowBase API Reference for rules and options.

There are two types of topics available:

InstantTopicUserListImpl supports all functionality in InstantTopicImpl and adds userList support. See chapter below for further description about userList.

Message formats

Two types of message formats are supported:

The TEXT message format is a plain text topic where the clients send and receive text messages (or anything coded as text). The message does not contain who sent the message or who the message is for, unless the clients add that information themselves.

The IKB message format adds structure to the messages and adds support for detecting who sent the message, who the message is for (private messages) and a message type. See Topic name and topic options in the iKnowBase API Reference for details regarding the IKB message format for requests and responses.

IKB message format is mandatory on userList (InstantTopicUserListImpl) topics.

Public and private messages

For the TEXT message format, all messages are public.

For the IKB message format, messages can be sent to a specific user (private message) by setting the recipients username in the toUserName property of the message.

Example public message in IKB-format sent by IKBUSER1:

Request
{
	"toUserName":""
	,"messageType":"USER_MSG"
	,"data":"This is a public message"
}
Response
{
	"toUserName":""
	,"fromUser":{
			"guid":"9BEA12EB56126795E040000A180038B7"
			,"id":1111
			,"username":"IKBUSER1"
			,"dn":"IKBUSER1"
			,"label":"IKB User1"
		}
	,"messageType":"USER_MSG"
	,"correlationId":null
	,"data":"This is a public message"
}

Example public message in IKB-format sent by IKBUSER1 to IKBUSER2 :

Request
{
	"toUserName":"IKBUSER2"
	,"messageType":"USER_MSG"
	,"data":"This is a public message"
}
Response
{
	"toUserName":"IKBUSER2"
	,"fromUser":{
			"guid":"9BEA12EB56126795E040000A180038B7"
			,"id":1111
			,"username":"IKBUSER1"
			,"dn":"IKBUSER1"
			,"label":"IKB User1"
		}
	,"messageType":"USER_MSG"
	,"correlationId":null
	,"data":"This is a public message"
}

User list support

The server will keep a list of all connected users to a topic if the topic is configured with option “userList=true”. A user is present at the topic if the user has one or more active connections.

When user list support is activated, the clients may use any of the following subscription options :

The Instant APIs also support server requests providing on demand alternatives for these subscription options, see

requestUserList

If the client subscribes with requestUserList, the client will receive a list of all users connected to the topic after the connection has joined. The returned list contains objects of type UserReference, which contains guid, id, username, dn and label, where label is the user’s "<firstname_if_any> <lastname>" as registered in iKnowBase User Directory.

The user list message is a private message sent to the user’s connection that joined the topic.

Example message payload in IKB-format for requestUserList for user IKBUSER1 on a topic where IKBUSER2 was also present:

{
	"toUserName":"IKBUSER1"
	,"fromUser":{
			"guid":null
			,"id":0
			,"username":"ikb$instant"
			,"dn":null
			,"label":"iKnowBase Instant Server"
		}
	,"messageType":"IKB.USERLIST.USERS"
	,"correlationId":null
	,"data":[
		{
			"guid":"9BEA12EB56126795E040000A180038B7"
			,"id":1111
			,"username":"IKBUSER1"
			,"dn":"IKBUSER1"
			,"label":"IKB User1"
		}
		,{
			"guid":"9582B1E8B4AA4BDA9B7E0B6422A1D1F7"
			,"id":2222
			,"username":"IKBUSER2"
			,"dn":"IKBUSER2"
			,"label":"IKB User2"
		}
	]
}

subscribeUserListChanges

If the client subscribes with subscribeUserListChanges, the client will receive join and leave messages when a user joins or leaves the topic.

Join/leave messages are public messages and are sent to all users on the topic who subscribe to user list changes.

Example message payload in IKB-format for subscribeUserListChanges JOIN for user IKBUSER1:

{
	"toUserName":null
	,"fromUser":{
			"guid":null
			,"id":0
			,"username":"ikb$instant"
			,"dn":null
			,"label":"iKnowBase Instant Server"
		}
	,"messageType":"IKB.USERLIST.JOIN"
	,"correlationId":null
	,"data":{
			"guid":"9BEA12EB56126795E040000A180038B7"
			,"id":1111
			,"username":"IKBUSER1"
			,"dn":"IKBUSER1"
			,"label":"IKB User1"
		}
}

Example message payload in IKB-format for subscribeUserListChanges LEAVE for user IKBUSER1:

{
	"toUserName":null
	,"fromUser":{
            "guid":null
            ,"id":0
            ,"username":"ikb$instant"
            ,"dn":null
            ,"label":"iKnowBase Instant Server"
        }
	,"messageType":"IKB.USERLIST.LEAVE"
	,"correlationId":null
	,"data":{
            "guid":"9BEA12EB56126795E040000A180038B7"
            ,"id":1111
            ,"username":"IKBUSER1"
            ,"dn":"IKBUSER1"
            ,"label":"IKB User1"
        }
}

APIs

The APIs are documented in the iKnowBase API Reference:

Installation and setup

See the iKnowBase Installation Guide .

Deployment and scaling

The Instant Server does not support application server clustering and a specific topic is required to exist in one JVM only to enable communication between clients on that topic. Clients can only communicate with other clients on the same JVM.

To support more traffic / connections than one server can handle, the topics can be divided among multiple servers:

The routing can be done by a load balancer with URL routing capabilities, as the topic name is part of the HTTP Request URL. This routing will be transparent for the connected clients.

An alternative to routing via load balancer is to use Cross Origin Resource Sharing (CORS) support, enabling clients to connect directly to a server host:port different from where the web page was loaded. The CORS address MUST match the protocol used on the webpage. If the web page uses HTTPS, then the CORS address must also be HTTPS.

NOTE: Only one Instant Server can consume messages from the PLSQL API. Enable/disable with Installation Property com.iknowbase.instant.aq.enabled.

Security

Authentication

The Instant Server offers protected services that requires client authentication.

Authentication to the Instant Server can be accomplished through either

  1. Use Secure Token (recommended) or
  2. Direct application container authentication

Once the client connection has been authenticated, the Instant Server will store the user’s identity for that specific connection as long as the connection is alive.

If the client tries to subscribe to a service that requires authentication before the client has authenticated, the subscribing request will receive a “HTTP 401 Unauthorized” response and the asynchronous connection will be terminated.

Authenticating with Secure Token

A user that is already authenticated to the /ikbViewer application can get a Secure Token (use Freemarker or Groovy support) and submit this when connecting to /ikbInstant. /ikbInstant will verify the token and retrieve the user’s identity without any user interaction.

To use Secure Token Authentication:

  1. Configure the SecureTokenEngine , see iKnowBase Installation Guide.
  2. Add the user’s Secure Token to the Instant subscribe request. (Available when using Freemarker and Groovy)
  3. Use default Instant servletURL /ikbInstant/ikbInstant

Authenticating with direct application container authentication

Authentication can also be done without Secure Token support. The container is responsible for authenticating the request and may require user interaction.

To use direct application container authentication:

  1. Use protected Instant servletURL /ikbInstant/private/ikbInstant

Authorization

Feature Authentication Required privilege Comment
No topic options on public servlet URL NOT NEEDED Not applicable
No topic options on private servlet URL REQUIRED Authenticated Used for direct application container authentication support
messageFormat=IKB topic option BENEFITS Not applicable Authentication enables usage of fromUser and toUserName
userList=true topic option REQUIRED Authenticated Only authenticated users can access a userList topic
ikb$console REQUIRED Authenticated and administrator Administration and monitoring

Private messages

A message can be targeted to a specific user, identified by the user’s username. The Instant Server guarantees that the message is only delivered to connections authenticated with that username.

This service requires that

  1. The topic is configured with the “IKB” message format.
  2. The publisher includes the recipient’s username in the “toUserName” property of the message.
  3. The recipient must be authenticated and connected for the message to be delivered.

Monitoring

Standard iKnowBase monitoring service ikb$console is available for the application. It is equipped with a separate Instant tab with information about topics, options, users and connection information.

Building solutions

See iKnowBase API Reference:

Project wide settings

The following code is typically added to a template or a reusable page component. This includes the necessary JavaScript and sets default options avoiding code copy on every Instant enabled page.

Project wide sample basic

<script src="/ressurs/iknowbase/iknowbase-instant-min.js"></script>
<script>
// Set project-wide defaults; typically added in layout template with html-header
iKnowBase.Instant.setDefaultOptions({
    subscriptionOptions: {
        // Not using any custom options
    },
    atmosphereOptions: { 
        // Using a project specific onOpen function. Optional.       
        onOpen: function (response) { iKnowBase.log ("request.onOpen (global)", response); }
    }
});

Project wide sample with secure token authentication

<script src="/ressurs/iknowbase/iknowbase-instant-min.js"></script>

[#ftl]
[#if context.user.isLoggedOn]
	[#assign secureTokenAuth =  "'_ikbUserToken':" + "'" + context.user.token.value + "'"]
[#else]
	[#assign secureTokenAuth = '']
[/#if]

<script>
// Set project-wide defaults; typically added in layout template with html-header
iKnowBase.Instant.setDefaultOptions({
    subscriptionOptions: {
        ${secureTokenAuth} // Authentication header from ikbViewer
    },
    atmosphereOptions: { 
        // Using a project specific onOpen function. Optional.       
        onOpen: function (response) { iKnowBase.log ("request.onOpen (global)", response); }
    }
});

Project wide sample with secure token authentication and CORS enabled

CORS configuration can be enabled in project wide settings.

NOTE: CORS must be enabled in server configuration as well, see InstantServerConfiguration CORS option.

<script src="/ressurs/iknowbase/iknowbase-instant-min.js"></script>

[#ftl]
[#if context.user.isLoggedOn]
    [#assign secureTokenAuth =  "'_ikbUserToken':" + "'" + context.user.token.value + "'"]
[#else]
    [#assign secureTokenAuth = '']
[/#if]

<script>
// Set project-wide defaults; typically added in layout template with html-header
iKnowBase.Instant.setDefaultOptions({
    servletURL: "http://CORS_SERVER_NAME:CORS_SERVER_PORT/ikbInstant/ikbInstant", //CORS: URL to servlet - the page itself should be served through a different URL
    subscriptionOptions: {        
        ${secureTokenAuth} // Authentication header from ikbViewer
    },
    atmosphereOptions: { 
        enableXDR: true, // Enable CORS
        // Using a project specific onOpen function. Optional.       
        onOpen: function (response) { iKnowBase.log ("request.onOpen (global)", response); }
    }
});

Instant subscribe with CORS

CORS configuration can be enabled during subscribe.

NOTE: CORS must be enabled in server configuration as well, see InstantServerConfiguration CORS option.

iKnowBase.Instant.Atmosphere.subscribe({           
     servletURL: "http://CORS_SERVER_NAME:CORS_SERVER_PORT/ikbInstant/ikbInstant", //CORS: URL to servlet - the page itself should be served through a different URL
     topicName: "/Topic1",
     subscriptionOptions: {
         // not using any custom options
     },
     atmosphereOptions: {
         enableXDR: true, // Enable CORS
         onMessage: onMessage // override onMessage
     }
});

Simple Web to Web Client using text messages

This sample enables web clients to send and receive messages on the specified topic using messageFormat=TEXT.

Prerequisite: Included project wide settings basic (see Building solutions > Project wide settings basic ).

// Page-specific application script
(function () {
   
   var topicName = "/Topic1";                   // Using default messageFormat=TEXT for this topic
   var channel;                                  // Reference to topic connection. Used for publish and close.
  
   function onMessage(response) {
      iKnowBase.log ("MySample.onMessage", response);         
      if (response.status == 200) { // HTTP status code=200 means normal response.        
         $('#messages ul').prepend($('<li></li>').text("Text message received: " + response.responseBody));         
      }else{
         iKnowBase.log('ERROR: Expected HTTP status code 200, but got HTTP status=' + response.status, response);
      }    
   }    
   
   function subscribe() {
       channel = iKnowBase.Instant.Atmosphere.subscribe({           
           topicName: topicName,
           subscriptionOptions: {
               // Not using any custom options
           },
           atmosphereOptions: {
               onMessage: onMessage // Use page specific onMessage callback
           }
      });
   }                                                               
    
   function sendMessage(){
      var message = jQuery("#messageToSend").val(); // Retrieve the message
      iKnowBase.log("sendMessage: " + message);     // Log the message
      channel.push({data: message});                // Send the message to topic
      jQuery("#messageToSend").val("");             // Clear the input message element   
    }

    window.MySample = {
        subscribe: subscribe,
        sendMessage: sendMessage
    }

}());

MySample.subscribe(); // Subscribe to topic

</script>

<div>
   <h4>type your message here:</h4>
   <input id='messageToSend' type='text'/><button id='sendMessage' name='sendMessage' type='button' onClick='MySample.sendMessage()'>Send message</button>
</div>


<div id="messages">
   <h4>Topic messages</h4>
	<ul>
   </ul>
</div>

Simple Web to Web Client using IKB messages and secure token authentication

This sample enables web clients to send and receive messages on the specified topic using messageFormat=IKB.

Prerequisite: Included project wide settings with authentication (see Building solutions > Project wide sample with secure token authentication ).

// Page-specific application script
(function () {
   
   var topicName = "/Topic1?messageFormat=IKB";  // Using messageFormat=IKB for this topic
   var channel;                                  // Reference to topic connection. Used for publish and close.
  
   function onMessage(response) {
      iKnowBase.log ("MySample.onMessage", response);         
      if (response.status == 200) { // HTTP status code=200 means normal response.         
         try {
              // First decode the message_format=IKB wrapping as JSON
              var ikbMsg = jQuery.parseJSON(response.responseBody);
         } catch (e) {
              iKnowBase.log('This does not look like a valid JSON: ',response.responseBody);
              return;
         }          
          
         $('#messages ul').prepend($('<li></li>').text("IKB message received: " + 
                                                        "fromUser=" + ((ikbMsg.fromUser)?ikbMsg.fromUser.label:null) +
                                                        ", toUserName=" + ikbMsg.toUserName +  
                                                        ", messageType=" + ikbMsg.messageType + 
                                                        ", data=" + ikbMsg.data));      
      }else{
         iKnowBase.log('ERROR: Expected HTTP status code 200, but got HTTP status=' + response.status, response);
      }    
   }    
   
   function subscribe() {
       channel = iKnowBase.Instant.Atmosphere.subscribe({           
           topicName: topicName,
           subscriptionOptions: {
               // Not using any custom options
               // Authentication was added in project wide settings, but could also be added here
           },
           atmosphereOptions: {
               onMessage: onMessage // Use page specific onMessage callback
           }
      });
   }                                                               
    
   function sendMessage(){
      var message = jQuery("#messageToSend").val(); // Retrieve the message
      iKnowBase.log("sendMessage: " + message);     // Log the message      
      channel.push({                                // Send the message to topic
            toUserName: ''
            , messageType: 'SAMPLE_MESSAGE'
            , data: message 
         });                
      jQuery("#messageToSend").val("");             // Clear the input message element   
    }

    window.MySample = {
        subscribe: subscribe,
        sendMessage: sendMessage
    }

}());

MySample.subscribe(); // Subscribe to topic

</script>

<div>
   <h4>type your message here:</h4>
   <input id='messageToSend' type='text'/><button id='sendMessage' name='sendMessage' type='button' onClick='MySample.sendMessage()'>Send message</button>
</div>


<div id="messages">
   <h4>Topic messages</h4>
	<ul>
   </ul>
</div>

Chat With User List Support

This sample shows a simple chat client with userList support.

Prerequisite: Included project wide settings with authentication (see Building solutions > Project wide sample with secure token authentication ).

// Page-specific application script
(function () {
   
   var topicName = "/Topic1?messageFormat=IKB&userList=true";  // Using messageFormat=IKB for this topic
   var channel;                                                // Reference to topic connection. Used for publish and close.
  
   function onMessage(response) {
      iKnowBase.log ("MySample.onMessage", response);         
      if (response.status == 200) { // HTTP status code=200 means normal response.         
         try {
              // First decode the message_format=IKB wrapping as JSON
              var ikbMsg = jQuery.parseJSON(response.responseBody);
         } catch (e) {
              iKnowBase.log('This does not look like a valid JSON: ',response.responseBody);
              return;
         }   
         
         // Check if this is a userList message from the Instant Server
         if(ikbMsg.messageType.indexOf("IKB.USERLIST")>-1){
         
            if(ikbMsg.messageType.indexOf("IKB.USERLIST.USERS")>-1){
               // USERLIST: Add the users to the displayed user list, if not already present
               for(var i=0;i<ikbMsg.data.length;i++){
                  if($("#members ul").find("[name='"+ikbMsg.data[i].username+"']").length==0){
                     $("#members ul").append("<li name='"+ikbMsg.data[i].username+"'>"+ikbMsg.data[i].label+" ("+ikbMsg.data[i].username+")</li>");
                  } 
               }                    
                     
            }else if(ikbMsg.messageType.indexOf("IKB.USERLIST.JOIN")>-1){
            	   // JOIN: Add the user to the displayed user list, if not already present
               if($("#members ul").find("[name='"+ikbMsg.data.username+"']").length==0){
                  $("#members ul").append("<li name='"+ikbMsg.data.username+"'>"+ikbMsg.data.label+" ("+ikbMsg.data.username+")</li>");
               } 
                    
            }else if(ikbMsg.messageType.indexOf("IKB.USERLIST.LEAVE")>-1){
               // LEAVE: Remove the user from the displayed user list
               $("#members ul").find("[name='"+ikbMsg.data.username+"']").remove();
            }
         }else{
            // Normalt user message - display in chat
         		$('#messages ul').prepend($('<li></li>').text("IKB message received: " + 
                                                        "fromUser=" + ((ikbMsg.fromUser)?ikbMsg.fromUser.label:null) +
                                                        ", toUserName=" + ikbMsg.toUserName +  
                                                        ", messageType=" + ikbMsg.messageType + 
                                                        ", data=" + ikbMsg.data)); 
         }       
          
              
      }else{
         iKnowBase.log('ERROR: Expected HTTP status code 200, but got HTTP status=' + response.status, response);
      }    
   }    
   
   function subscribe() {
       channel = iKnowBase.Instant.Atmosphere.subscribe({           
           topicName: topicName,
           subscriptionOptions: {
               requestUserList: true,          // We want an initial user list
               subscribeUserListChanges: true  // We want to recieve joing/leave messages
               // Authentication was added in project wide settings, but could also be added here
           },
           atmosphereOptions: {
               onMessage: onMessage // Use page specific onMessage callback
           }
      });
   }                                                               
    
   function sendMessage(){
      var message = jQuery("#messageToSend").val(); // Retrieve the message
      iKnowBase.log("sendMessage: " + message);     // Log the message      
      channel.push({                                // Send the message to topic
            toUserName: ''
            , messageType: 'SAMPLE_MESSAGE'
            , data: message 
         });                
      jQuery("#messageToSend").val("");             // Clear the input message element   
    }

    window.MySample = {
        subscribe: subscribe,
        sendMessage: sendMessage
    }

}());

MySample.subscribe(); // Subscribe to topic

</script>

<div>
   <h4>type your message here:</h4>
   <input id='messageToSend' type='text'/><button id='sendMessage' name='sendMessage' type='button' onClick='MySample.sendMessage()'>Send message</button>
</div>


<div id="messages">
   <h4>Topic messages</h4>
	<ul>
   </ul>
</div>

<div id="members">
  <h4>Members</h4>
  <ul>
  </ul>
</div>

Content updates notifications Using Database Integration

This sample shows notifications when changes to documents relevant for the content viewer are available.

Prerequisite: Included project wide settings with authentication (see Building solutions > Project wide sample with secure token authentication ).

The building blocks for this sample are:

Instant publish/subscribe sample code

// Page-specific application script
(function () {
   
   var topicName = "/Topic1";            // Using default messageFormat=TEXT for this topic
   
   function onMessage (response) {
     iKnowBase.log ("blog.onMessage", response);
	  if (response.status == 200) {
		  iKnowBase.notify({
		    type:'info',
			  title:'Updates for Content Viewer documents are available',
			  text:response.responseBody,
			  duration:5000 // Remove after 5 seconds
		  });	     
      }      
   }
   
   function subscribe() {
      iKnowBase.Instant.Atmosphere.subscribe({           
          topicName: topicName,
          subscriptionOptions: {
              // Not using any custom options
          },
          atmosphereOptions: {
              onMessage: onMessage // Use page specific onMessage callback
          }
      });
   }                                                               

   window.MySample = {
      subscribe: subscribe
   }

}());

MySample.subscribe(); // Subscribe to topic

</script>

Event

The Event is set up in /ikbStudio/advanced/events with

IKB database function mapping

The database function is set up in /ikbStudio/advanced/dbfunctions with

Database procedure PUBLISH_TOPIC1

CREATE OR REPLACE
PROCEDURE PUBLISH_TOPIC1
(
  PARAMS      IN    OT_EVENTPARAMS   
  , OLDREC    IN    OT_DOCUMENT    
)
IS 
  P_TOPIC         VARCHAR2(200);
  P_DATA          CLOB;
  P_FROM_USERNAME VARCHAR2(200);
  P_TO_USERNAME   VARCHAR2(200);
  P_MESSAGE_TYPE  VARCHAR2(200);
BEGIN
  P_TOPIC         := '/Topic1';
  P_DATA          := 'Event triggered due to id: '||params.object_id;
  P_FROM_USERNAME := NULL;
  P_TO_USERNAME   := NULL;
  P_MESSAGE_TYPE  := NULL;
  IKB_INSTANT.PUBLISH(
      P_TOPIC
      , p_DATA
      , P_FROM_USERNAME
      , P_TO_USERNAME
      , P_MESSAGE_TYPE
  );
END;

Livefeed Using Database Integration

This is the same example as “Content updates notifications Using Database Integration”, but instead of just displaying a notification we’ll reload the portlet and display it’s content.

Warning: Fetching server content based on instant notifications does come with a significant cost. Whenever there event is triggered, all clients currently displaying (and subscribing) to the live feed will immediately request new content. If there are many clients listening, they will all generate requests at the same moment. This type of live feed is not cached by the iKnowBase application and a high number of clients may overload the system.

First we’ll mark the Content Viewer Page Component with markup id = “BlogDocuments”. We’ll use this ID when reloading.

Second, change the onMessage function from iKnowBase.notify to

iKnowBase.PageEngine.reloadComponent("BlogDocuments"); // Reload component by markup id on any message

Livefeed Using Cache Refresh Events

See Instant notifications of content cache updates in the iKnowBase Development Guide > Performance.