Wednesday 12 April 2017

Salesforce Streaming API



Use Streaming API to receive notifications for changes to Salesforce data that match a SOQL query you define, in a secure and scalable way.

These events can be received by:

• Pages in the Salesforce application.
• Application servers outside of Salesforce.
• Clients outside the Salesforce application.

The sequence of events when using Streaming API is as follows:
1. Create a PushTopic based on a SOQL query. This defines the channel.
2. Clients subscribe to the channel.
3. A record is created, updated, deleted, or undeleted (an event occurs). The changes to that record
are evaluated.
4. If the record changes match the criteria of the PushTopic query, a notification is generated by the
server and received by the subscribed clients.

Streaming API is useful when you want notifications to be pushed from the server to the client based
on criteria that you define. Consider the following applications for Streaming API:

Applications that poll frequently
Applications that have constant polling action against the Salesforce infrastructure, consuming
unnecessary API calls and processing time, would benefit from Streaming API which reduces the
number of requests that return no data.

General notification
Use Streaming API for applications that require general notification of data changes in an organization. This enables you to reduce the number of API calls and improve performance.

Note: You can use Streaming API with any organization as long as you enable the API. This includes
both Salesforce and Database.com organizations.

Push Technology

Push technology, also called the publish/subscribe model, transfers information that is initiated from a server to the client. This type of communication is the opposite of pull technology in which a request for information is made from a client to the server.

The information sent by the server is typically specified in advance. When using Streaming API, you specify the information that the client receives by creating a PushTopic. The client then subscribes to the PushTopic channel and is notified of events that match thePushTopic criteria.

In push technology, the server pushes out information to the client after the client has subscribed to a channel of information. For the client to receive the information, the client must maintain a connection to the server. Streaming API uses the Bayeux protocol and CometD, so the client to server connection is maintained through long polling.


Bayeux Protocol, CometD, and Long Polling

Streaming API uses the Bayeux protocol and CometD for long polling.

• Bayeux is a protocol for transporting asynchronous messages, primarily over HTTP.

• CometD is a scalable HTTP-based event routing bus that uses an AJAX push technology pattern known as Comet. It implements the Bayeux protocol. The Salesforce servers use version 2.0 of CometD.

• Long polling, also called Comet programming, allows emulation of an information push from a server to a client. Similar to a normal poll, the client connects and requests information from the server. However, instead of sending an empty response if information isn't available, the server holds the request and waits until information is available (an event occurs). The server then sends a complete response to the client. The client then immediately re-requests information. The client continually maintains a connection to the server, so it’s always waiting to receive a response. In the case of server timeouts, the client connects again and starts over.

Streaming API supports the following CometD methods:

Method Description:

Connect :  The client connects to the server.
Disconnect :  The client disconnects from the server.
Handshake :  The client performs a handshake with the server and establishes a long polling connection.
Subscribe : The client subscribes to a channel defined by a PushTopic. After the client subscribes, it can receive
messages from that channel. You must successfully call the handshake method before you can
subscribe to a channel.
Unsubscribe :  The client unsubscribes from a channel.


Streaming API Terms


Event : The creation, update, delete, or undelete of a record. Each event might trigger a notification.
Notification : A message in response to an event. The notification is sent to a channel to which one or more clients are subscribed.
PushTopic : A record that you create. The essential element of a PushTopic is the SOQL query. The PushTopic defines a Streaming API channel.

How the Client Connects

Streaming API uses the HTTP/1.1 request-response model and the Bayeux protocol (CometD implementation). A Bayeux client connects
to Streaming API in multiple stages.

1. Sends a handshake request.
2. Sends a subscription request to a channel.
3. Connects using long polling.

The maximum size of the HTTP request post body that the server can accept from the client is 32,768 bytes, for example, when you call
the CometD subscribe or connect methods. If the request message exceeds this size, the following error is returned in the response: 413 Maximum Request Size Exceeded. To keep requests within the size limit, avoid sending multiple messages in a single
request.

The client receives events from the server while it maintains a long-lived connection.

• If the client receives events, it should reconnect immediately to receive the next set of events. If the reconnection doesn't occur within 40 seconds, the server expires the subscription and the connection closes. The client must start over with a handshake and subscribe again.

• If no events are generated and the client is waiting and the server closes the connection, after two minutes the client should reconnect immediately.

If a long-lived connection is lost due to unexpected network disruption, CometD will automatically attempt to reconnect. If this reconnection is successful, clients must re-subscribe, since this new connection has gone through a re-handshake that removes previous subscribers. Clients can listen to the meta/handshake meta channel to receive notifications when a connection is lost and re-established.


Message Reliability

In API version 37.0 and later, Streaming API stores events for 24 hours, enabling you to replay past events. With durable streaming, messages aren’t lost when a client is disconnected or isn’t subscribed. When the client subscribes again, it can fetch past events that are within the 24-hour retention period. The ability to replay past events provides reliable message delivery.


Message Delivery Considerations

Multiple Notifications Within the Same Apex Transaction

In API version 36.0 and earlier, if multiple PushTopic notifications are sent for the same record within the same Apex transaction, only the last notification is sent. The earlier notifications are suppressed. For example, suppose a PushTopic is set up for insertions and updates of contact records, and the PushTopic query selects fieldA. If a contact is inserted and then an Apex trigger updates
fieldA, only the notification for the update is sent. No notification is sent for the contact creation. In API version 37.0 and later, all notifications for the same record in a single transaction are sent, and no notification is suppressed.

Message Durability

Salesforce stores events for 24 hours, so you can retrieve stored events during that retention window. The Streaming API event framework decouples event producers from event consumers. A subscriber can retrieve events at any time and isn’t restricted to listening to events at the time they’re sent.


Pre-Requisites for Streaming API

• The “API Enabled” permission must be enabled for your Developer Edition organization. This permission is enabled by default, but may have been changed by an administrator.

• The “Streaming API” permission must be enabled.

The logged-in user must have “Read” permission on the PushTopic standard object to receive notifications.

• The logged-in user must have “Create” permission on the PushTopic standard object to create and manage PushTopic records.

• The logged-in user must have “Author Apex” permissions to create a PushTopic by using the Developer Console.


Steps for creating push topic

Open the developer console

Click debug  - > Open Execute Anonymous Window.

Paste the following code and click execute

PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'InvoiceStatementUpdates';
pushTopic.Query = 'SELECT Id,Name,Status__c,Description__c from Invoice_Statement__c';
pushTopic.ApiVersion= 38.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';

insert pushTopic;

Because NotifyForOperationCreate, NotifyForOperationUpdate, NotifyForOperationDelete and
NotifyForOperationUndelete are set to true, Streaming API evaluates records that are created, updated, deleted, or undeleted and generates a notification if the record matches the PushTopic query. Because NotifyForFields is set to Referenced, Streaming API will use fields in both the SELECT clause and the WHERE clause to generate a notification. Whenever the fields Name, Status__c, or Description__c are updated, a notification will be generated on this channel.


Example: Interactive Visualforce Page

Step 1: Create an Object

Step 2: Create a PushTopic

1. Open the Developer Console.
2. Click Debug > Open Execute Anonymous Window.


3. In the Enter Apex Code window, paste in the following Apex code, and click Execute.

PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'InvoiceStatementUpdates';
pushTopic.Query = 'SELECT Id, Name, Status__c, Description__c FROM Invoice_Statement__c';
pushTopic.ApiVersion = 38.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';
insert pushTopic;


Step 3: Create the Static Resources


1) Download this static resource .zip file: streaming_api_interactive_visualforce_demo-v25.zip

2) From Setup, enter Static Resources in the Quick Find box, then select Static Resources to add the extracted files with the following names:

cometd.zip : cometd
demo.css : demo_css
demo.js : demo_js
json2.js : json2_js


Step 4: Create a Visualforce Page


<apex:page >

    <apex:includeScript value="{!$Resource.json2_js}" />
    <apex:includeScript value="{!URLFOR($Resource.cometd,'dojo/dojo.js')}" />
    <apex:includeScript value="{!$Resource.demo_js}" />
    <apex:stylesheet value="{!$Resource.demo_css}" />
    
        <script> var token = '{!$Api.Session_ID}';</script>
        
            <div id="demo">
            
                <div id="datastream"></div>
                
                <div id="input">
                
                    <div id="join">
                    
                        <table>
                        
                            <tbody>
                            
                                <tr>
                                    
                                    <td>&nbsp;</td>
                                    
                                    <td> Enter Topic Name </td>
                                    
                                    <td>
                                    
                                        <input id="topic" type="text" />
                                        
                                    </td>
                                    
                                    <td>
                                    
                                        <button id="subscribeButton" class="button">Subscribe</button>
                                        
                                    </td>
                                    
                                    
                                </tr>
                                
                             </tbody>
                          
                        </table>

                    </div>    
                          
                    <div id="joined">

                        <table>
                        
                            <tbody>
                            
                                <tr>
                                
                                    <td>
                                    
                                        <button id="leaveButton" clas="button"> Unsubscribe </button>
                                        
                                    </td>
                                    
                                </tr>
                                
                            </tbody>
                            
                        </table>
                        
                    </div>
                    
                </div>
                
            </div>
            
</apex:page>


Step 5: Test the PushTopic Channel


  1. Load the Visualforce page that you created in a Web browser
  2. In the text box, enter the channel name: /topic/InvoiceStatementUpdates.
  3. Click Subscribe to subscribe to the channel.
  4. Create or modify an InvoiceStatement in a different browser. You should see the event notification appear on the Visualforce page. The output should resemble the following:

{ "event": { "type": "created", "createdDate": "2016-11-30T13:37:52.000+0000" }, "sobject": { "Description__c": "test", "Id": "a002800000rNSJrAAO", "Status__c": "Open", "Name": "INV-0004" } }



Example: Visualforce Page


Step 1: Create an Object

Step 2: Create a PushTopic


1. Open the Developer Console.
2. Click Debug > Open Execute Anonymous Window.


3. In the Enter Apex Code window, paste in the following Apex code, and click Execute.

PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'InvoiceStatementUpdates';
pushTopic.Query = 'SELECT Id, Name, Status__c, Description__c FROM Invoice_Statement__c';
pushTopic.ApiVersion = 38.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';
insert pushTopic;



Step 3: Create the Static Resources

1) Download this static resource .zip file: streaming_api_interactive_visualforce_demo-v25.zip

2) From Setup, enter Static Resources in the Quick Find box, then select Static Resources to add the extracted files with the following names:

cometd.zip : cometd
demo.css : demo_css
demo.js : demo_js
json2.js : json2_js



Step4 : Create a Visualforce Page



<apex:page >

    <apex:includeScript value="{!$Resource.cometd}" />
    <apex:includeScript value="{!$Resource.jquery}" />
    <apex:includeScript value="{!$Resource.json2}" />
    <apex:includeScript value="{!$Resource.jquery_cometd}" />
    
    <script type="text/javascript">
    
    (function($){
    
        $(document).ready(function(){
        
            // Connect to the CometD endpoint
        
            $.cometd.init({
            
                url: window.location.protocol+'//'+window.location.hostname+'/cometd/24.0/',
                requestHeaders:{Authorization: 'OAuth {!$Api.Session_ID}'}
                            
            });
            
            //Subscribe to a topic. JSON-encoded update will be returned
            //in the callback
            
            $.cometd.subscribe('/topic/InvoiceStatementUpdates',function(message){
            
                $('#content').append('<p>Notification: '+
                
                                    'Channel: '+ JSON.stringify(message.channel) + '<br>'+
                                    'Record Name: '+ JSON.stringify(message.data.sobject.Name) + 
                                    '<br>' + 'ID: ' + JSON.stringify(message.data.sobject.Id) + 
                                    '<br>' + 'Event type: ' + JSON.stringify(message.data.event.type) +
                                    '<br>' + 'Created: '+JSON.stringify(message.data.event.createdDate)
                
                                    +'</p>');
            
            });
        
        
        });
    
    
    
    
    
    })(jQuery)
    
    
    function disconnect(){
    
        $.cometd.disconnect();
    
    }
    
    window.onbeforeunload = disconnect;
    
    </script>
    
    
    <body>
    
        <div id="content">
        
            <h1> Streaming API Test Page </h1>
            
            <p> This is a demonstration page for Streaming API. Notifications from the InvoiceStatementUpdates channel will appear here...</p>
        
        
        </div>
    
    
    </body>
    
    </apex:page>

/topic/InvoiceStatementUpdates is the push topic created in step2.


Step 5: Test the PushTopic Channel

1. Load the Visualforce page in a Web browser by using the following URL:

https://myinstance.salesforce.com/apex/StreamingPage where myinstance is the name of your
Salesforce instance, such as na1.


2. Create or modify an InvoiceStatement in a different browser. You should see the event notification appear on the Visualforce page.




Example: Lightning APP


Step 1: Create an Object

Step 2: Create a PushTopic


1. Open the Developer Console.
2. Click Debug > Open Execute Anonymous Window.


3. In the Enter Apex Code window, paste in the following Apex code, and click Execute.

PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'InvoiceStatementUpdates';
pushTopic.Query = 'SELECT Id, Name, Status__c, Description__c FROM Invoice_Statement__c';
pushTopic.ApiVersion = 38.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';
insert pushTopic;



Step 3: Create the Static Resources

1) Download this static resource .zip file: streaming_api_interactive_visualforce_demo-v25.zip

2) From Setup, enter Static Resources in the Quick Find box, then select Static Resources to add the extracted files with the following names:

cometd.zip : cometd
demo.css : demo_css
demo.js : demo_js
json2.js : json2_js



Step4 : Create a Lightning Component

StreamingComp.cmp

<aura:component controller="usersession">
    
<ltng:require scripts="{!join(',',$Resource.cometd,$Resource.jquery,$Resource.json2,$Resource.jquery_cometd)}" afterScriptsLoaded="{!c.doInit}" />

    
    
<lightning:buttonIcon iconName="utility:close" variant="bare" onclick="{! c.handleClick }" alternativeText="Close window." />

    <br />
    <br />
    <div id="content">
        
            <h1> Streaming API Test Page </h1>
            
            <p> This is a demonstration page for Streaming API. Notifications from the InvoiceStatementUpdates channel will appear here...</p>
        
        
    </div>
        
</aura:component>




StreamingComp.js

({

    doInit : function(component, event, helper) {
        
      //j$ = jQuery.noConflict();
     
        
        $(document).ready(function(){         
        
                        
         var sessionaction = component.get("c.getsessionid");
         var usersessionid;
        
        alert('before session call out');
        
        sessionaction.setCallback(this,function(response){
            
           var status = response.getState();
            
            if(status==="SUCCESS"){
                
                console.log(JSON.stringify(response.getReturnValue()));
                
                usersessionid = response.getReturnValue();
                
                console.log('usersessionid : ' +'OAuth '+usersessionid);
                $.cometd.init({
            
                url: window.location.protocol+'//'+window.location.hostname+'/cometd/24.0/',
                requestHeaders:{Authorization: 'OAuth '+usersessionid}
                            
            });
                
                //console.log('window location' + window.location.hostname);
            
            //Subscribe to a topic. JSON-encoded update will be returned
            //in the callback
            
            $.cometd.subscribe('/topic/InvoiceStatementUpdates',function(message){
            
                //console.log('json mesage data sobject name' +JSON.stringify(message.data.sobject.Name));
                
                $('#content').append('<p>Notification: '+
                                     
                                    'Channel: '+ JSON.stringify(message.channel) + '<br>'+
                                    'Record Name: '+ JSON.stringify(message.data.sobject.Name) + 
                                    '<br>' + 'ID: ' + JSON.stringify(message.data.sobject.Id) + 
                                    '<br>' + 'Event type: ' + JSON.stringify(message.data.event.type) +
                                    '<br>' + 'Created: '+JSON.stringify(message.data.event.createdDate)
                
                                    +'</p>');
            
            });
                
            }
            
        });
        
        
        $A.enqueueAction(sessionaction);             

            
        });
        
    },
    
    handleClick : function(component, event, helper) {

            alert('Daniel');
        
}
    
})


/topic/InvoiceStatementUpdates is the push topic created in step2.


UserSession Class

public class usersession{

    @AuraEnabled
    public static string getsessionid(){
    
        system.debug('User Session ID : ' + UserInfo.getSessionID());
        
        return UserInfo.getSessionID();
    
    }


}

Step 5: Test the PushTopic Channel

1. Test the lightning component using the lightning app

2. Create or modify an InvoiceStatement in a different browser. You should see the event notification appear on the lightning app page.



No comments:

Post a Comment